# Avalara Item Classification API

If you're subscribed to the Avalara Item Classification service, these APIs 
 allow you to submit products for Item Classification and retrieve the 
 corresponding HS Codes.

 **Notes**:
 - Avalara Item Classification is a billable service. If the service is not 
 enabled, the API will not provide a response.
 - In the development environment (Sandbox), the service will not 
 return HS Codes. Instead, requests will remain in a pending status by default.
 Use the `hs_code_test` parameter in your Sandbox/integration environment to pass 
 an HS Code directly. In this case the product will not be reviewed by any operator,
 and a response will be sent back in a matter of minutes.

 There are two subscription options for the Item Classification API:
 - **Item Classification With Storage**: Your item metadata is automatically 
 stored as an [Avalara
 Item](https://developer.avalara.com/api-reference/avatax/rest/v2/models/ItemModel/) 
 object. This enables easy referencing of your items and metadata throughout
 Avalara using your own SKU.
 - **Item Classification Without Storage**: You have the flexibility to store 
 your classified items in a manner that best suits your needs. If you opt 
 for this, you can optionally set up a webhook to receive your classifications.

Source: https://developer.avalara.com/products/managed-and-premium-tariff-code/api/

**Version:** 16.0.1-oas3
**Base URL:** https://api-sandbox.classification.avalara.net

---

## Endpoints

### CreateHSClassificationRequest

#### Create an HS classification request (auto-classifies synchronously for Auto HS / Auto HS Pro / Auto HS ICP customers; otherwise queues for manual classification).

`POST /api/v2/companies/{companyId}/classifications/hs`

Submit a product for HS classification for one or more countries of
destination. Each product (item) must be uniquely identified by itemCode
for a particular company. It is recommended to use your internal SKU
number as itemCode. Item classifications belong to the company you
designate.

## Dual-mode behavior

The same endpoint serves both auto-classification and manual
classification customers. The mode is chosen server-side based on
customer entitlement and the `async` query parameter:

- **Auto classification path** (synchronous prediction). Selected when:
  - The customer is entitled to **Auto HS**, **Auto HS Pro**, or **Auto HS ICP**, **and**
  - `async` is **not** `true` (i.e. omitted or `false`).

  The request is internally routed to the ML-based auto-classify flow
  (previously exposed as `/classifications/hscodes/auto`, now deprecated
  and removed from the public surface). The classification result is
  returned **synchronously** in the response body — there is no need to
  poll the GetHSClassification endpoint afterwards.

- **Manual classification path** (asynchronous parking-lot creation).
  Selected when:
  - The customer is **not** entitled to Auto HS / Auto HS Pro / Auto HS ICP, **or**
  - `async=true` is supplied (force manual flow even for entitled customers).

  The item is queued for manual classification. The response carries a
  `PENDING` status and the classification result can be retrieved later
  via `GET /classifications/hs/{hsClassificationId}`.

If the auto-classify path is selected but fails before invoking the
prediction service (e.g. authentication or payload conversion error),
the request automatically falls back to the manual classification path
so the call still succeeds.

## Request body

Both modes accept the **same** request body shape
(`HSClassificationModel` / `HSClassificationWithComplianceModel`).
Existing integrations do not need to change their payload to benefit
from auto-classification: simply enable Auto HS on the customer.

## Limits

- **Manual path:** maximum payload size of approximately 60KB. Exceeding
  this returns **413 Payload Too Large**. Split bulk-country requests if
  you hit the limit.
- **Auto path:** combined count (items × countries of destination) must
  not exceed the configured per-request limit (e.g. 10). Exceeding it
  returns **413 Payload Too Large**.

**Parameters:**

| Name | Type | In | Required | Description |
|---|---|---|---|---|
| `companyId` | integer | path | Yes | The ID of the company that owns this item. This is your integer company ID, not the string company code. |
| `customerId` | string | query | No | The unique identifier of the customer (for multi-tenant scenarios). When omitted, the customer is resolved from the authentication token. |
| `returnIcAccountId` | boolean | query | No | When `true`, the response includes the Item Classification account id (`icAccountId`) for each classification entry. Defaults to `false` when not supplied. |
| `async` | boolean | query | No | Forces the **manual classification path** (parking-lot creation) even when the customer is entitled to Auto HS / Auto HS Pro / Auto HS ICP. When omitted or `false`, entitled customers are auto-classified synchronously. When `true`, the item is always queued for manual classification and the response status will be `PENDING`. |
| `Context` | string | header | No | Optional contextual metadata propagated to downstream services. |


### GetHSClassification

#### Returns the HS classification code. The status field reflects the actual state of the classification request.

`GET /api/v2/companies/{companyId}/classifications/hs/{hsClassificationId}`

Returns the HS classification code. The status field reflects the actual state of the classification request.

**Parameters:**

| Name | Type | In | Required | Description |
|---|---|---|---|---|
| `companyId` | integer | path | Yes | The ID of the company that owns this item. This is your integer company ID, not the string company code. |
| `hsClassificationId` | integer | path | Yes | The hsClassificationId used to identify a request was returned in the response of the CreateHSClassificationRequest method. |


### HSCodeValidationRequest

#### Validate HS Codes

`POST /api/v2/companies/{companyId}/classifications/hscodes/validate`

Validates a list of HS codes for a given customer and company.
There is a limit to the number of HS codes that can be validated in a single request.
Requests exceeding this limit will be rejected with a 413 Payload Too Large error.

The customer must be enabled for HS code validation service.

**Parameters:**

| Name | Type | In | Required | Description |
|---|---|---|---|---|
| `companyId` | string | path | Yes | The unique identifier of the company. |
| `customerId` | string | query | Yes | The unique identifier of the customer. |
| `HEADER_CONTEXT` | string | header | No | Optional header context. |


### HSCodeVerificationRequest

#### Verify HS Code for Product

`POST /api/v2/companies/{companyId}/classifications/hscodes/verify`

Verifies whether a provided HS code is appropriate for a given product using ML-based classification.

**Behavior:**
- If the HS code is verified as appropriate, returns `verified: true`
- If the HS code is NOT verified, automatically submits the product for classification and returns the classification response

**Requirements:**
- The customer must be enabled for HS code validation service
- HS code must be 6-12 digits, optionally followed by up to 2 letters (e.g., 7323997000, 7323997000AB)
- All standard classification fields are required (companyId, itemCode, description, itemGroup, countryOfDestination)

**Performance:**
- Typical response time: 1-2 seconds
- Timeout: 5 seconds
- Circuit breaker protection for service resilience

**Parameters:**

| Name | Type | In | Required | Description |
|---|---|---|---|---|
| `companyId` | string | path | Yes | The unique identifier of the company. |
| `customerId` | string | query | No | The unique identifier of the customer (for multi-tenant scenarios). |
| `Context` | string | header | No | Optional header context. |


### WebhookCallback

#### Webhook Callback Endpoint

`POST /webhook/callback`

This is the endpoint that clients need to implement to receive webhook callbacks when classifications are completed.
Only clients who have specifically opted to receive webhook callbacks need to implement this endpoint.

**Authentication:**
The webhook callback supports two authentication methods:
- Basic Authentication: Avalara will send an Authorization header with "Basic {token}"
- OAuth: Avalara will send an Authorization header with "Bearer {token}"

**Response Requirements:**
- The endpoint should return HTTP 200 or 201 on success
- The recommended response format is: {"name":"API_RESPONSE","value":"SUCCESSFUL"}
- For errors, return HTTP 400 with: {"name":"API_RESPONSE","value":"ERROR"}

**Retry Behavior:**
If the webhook call fails due to server connectivity issues, the system will automatically retry the call.
Clients should ensure their webhook endpoint is reliable and responds quickly to avoid retry delays.

---

## Models

### WebhookCallbackRequest

The webhook callback payload that will be sent to the client's webhook endpoint when a classification is completed.
Only clients who have specifically opted to receive webhook callbacks need to implement this endpoint.
This is an optional feature for "Item Classification Without Storage" customers.

**Authentication:**
The webhook callback supports two authentication methods:
- Basic Authentication: Requires an API key configured in the Avalara system
- OAuth: Requires an OAuth token endpoint to be configured in the Avalara system

**Conditional Fields:**
- The `possibleHsCodes` field is only included when the `broker` parameter is set to "true" and there are alternative HS codes available

**Retry Behavior:**
If the webhook call fails due to server connectivity issues, the system will automatically retry the call.

| Property | Type | Description |
|---|---|---|
| `hsClassificationId` | string | The id of the HS classification request that was completed. |
| `companyId` | string | The ID of the company that owns this item. |
| `itemCode` | string | The unique item code (typically your SKU) that was classified. |
| `countryOfDestination` | string | The country code for which the classification was performed. |
| `status` | string | The status of the classification request. |
| `hsCode` | string | The HS classification result. |
| `rationale` | string | Explanation of the classification decision when available. |
| `possibleHsCodes` | string | Alternative HS codes that could apply to this item, when available.
This is provided as a stringified JSON array. |
| `compliance` | object | Compliance information if compliance_flagging was enabled. |

### HSClassificationModel

| Property | Type | Description |
|---|---|---|
| `id` | string | The id of the HS classification request. This id is created by CreateHSClassificationRequest and returned in the response. |
| `item` | ItemModel |  |
| `activity` | string | The required classification activity for the request. Accepted values are: HS_FULL : full HS code classification (country specific). This is the default activity if no value is specified in the request. HS6: 6 digits HS code classification |
| `countryOfDestination` | object |  |
| `hsCode` | string | This is the HS classification result. It’ll be returned in the body for GetHSClassification method. |
| `status` | string | This value is returned by get HS Classification method. It’ll be ignored if it’s provided in the request. |
| `resolution` | string | This value will be returned by getHSClassification method only if an item cannot be classified (status=CANNOT_BE_CLASSIFIED). It contains a detailed description of the issue. It’ll be ignored if it’s provided in the request. |
| `confidence` | string | If the information provided in the request is not enough, an accurately classification might not be possible. In this case, the assumption made for classification will be returned in this field. |
| `confidenceDescription` | string | This is a detailed description of the assumptions made in order to classify an item when information provided in the request is not enough (e.g. similar product URL, product number or anything which can be used as identifier behind the classification logic). |
| `possibleHsCodes` | string | Alternative HS codes that could apply to this item, when available. This field is only included when the broker parameter is set to "true" and there are alternative HS codes available. Provided as a stringified JSON array. |
| `productUpdate` | boolean | Indicates whether the product information was updated during classification. |
| `validCODs` | array | List of valid country codes that were successfully processed |
| `invalidCODs` | array | List of invalid country codes that could not be processed |

### ItemModel

| Property | Type | Description |
|---|---|---|
| `id` | integer | A unique id generated by Avalara Classification System |
| `companyId` | integer | The unique ID number of the company that owns this item. |
| `itemCode` | string | A unique code representing this item. It’s recommended to use the SKU number. |
| `parentCode` | string | Use the  parentCode to group product variants. Variants are a group of similar items that only differ from one another by product details like size, color, material, pattern, age group or size . |
| `description` | string | A short description of the product. It’s also referred as product title or name. |
| `summary` | string | A long description of the product. |
| `itemGroup` | string | Product category breadcrumbs. This is the full path to the category where item is included. Categories should be separated by ` > `. |
| `createdDate` | string | A long description of the product. |
| `classificationParameters` | array |  |
| `parameters` | array |  |

### ItemParameterModel

| Property | Type | Description |
|---|---|---|
| `parameters` | array | The system has predefined list of parameter names that are known and
processed accordingly (see enum).

Predefined parameters for a compliance enrichment
request include: compliance_flagging, country_of_export,
country_of_manufacture, manufacturer_name, compliance_start_date,
compliance_end_date. When `compliance_flagging` is set to `true`,
`country_of_export` is **required** (otherwise no compliance call
is made for that country of destination) and
`country_of_manufacture` + `manufacturer_name` are strongly
recommended for accurate duty, FTA, CVD/ADD and restrictions
lookups.

For a brokerage response, where classification provides an HS6 with
optional full HS codes for your brokers to select from requires the
broker parameter set to true. 

For a premium response, where classifications are returned with full
explanations of rationale require the
premium parameter set to true. 

The system also supports 
custom parameters. For custom parameters, the name is not predefined
and should be provided in the request. |

### HSClassificationWithComplianceModel

### Compliance

| Property | Type | Description |
|---|---|---|
| `id` | string | The unique ID number for the quote |
| `countryOfExport` | string | Two characters ISO 3166 code identifying the country |
| `countryOfImport` | string | Two characters ISO 3166 code identifying the country |
| `countryOfManufacture` | string | Two characters ISO 3166 code identifying the country |
| `hscode` | string | Country specific hs code value. |
| `manufacturerName` | string | Name of the Manufacturer Company. |
| `productName` | string | Name of the product. |
| `duty` | Duty |  |
| `hasCVD` | boolean | is given request parameter has CVD(Countervailing Duty) rates. |
| `cvds` | array |  |
| `hasADD` | boolean | is given request parameter has ADD (Anti-Dumping Duty) rates. |
| `adds` | array |  |
| `hasRestrictions` | boolean | is given request parameter have restrictions for countryOfImport. |
| `hasPGA` | boolean | is given request parameter PGA restrictions for countryOfImport. |
| `restrictions` | array |  |

### Duty

| Property | Type | Description |
|---|---|---|
| `calculationBasis` | string | Basis for duty calculation (e.g., PRICE, QUANTITY, CIF) |
| `mfn` | Rate |  |
| `hasPunitiveRate` | boolean | Indicates if punitive rates apply |
| `punitiveRates` | array |  |
| `hasFTARate` | boolean | Indicates if Free Trade Agreement rates apply |
| `ftaRates` | array |  |

### CvdAdd

| Property | Type | Description |
|---|---|---|
| `productName` | string | the name of the product that need to ship |
| `manufacturerName` | string | Name of the Manufacturer Company. |
| `rate` | Rate |  |

### Rate

| Property | Type | Description |
|---|---|---|
| `rate` | string | Rate value |
| `effectiveRate` | string | Effective rate value |
| `uom` | string | Unit of measurement (e.g., percentage, kilogram, count) |
| `currency` | string | Currency of the rate, if applicable |

### PunitiveRate

| Property | Type | Description |
|---|---|---|
| `rate` | Rate |  |
| `stackable` | boolean | Indicates whether this punitive rate should be applied **on top of** all other duty components (MFN, FTA). |
| `taxOnTax` | boolean | Indicates whether the punitive rate is **compounded**, i.e. calculated as: rate + surchargeRate + (rate * surchargeRate) |
| `appliesUnderDeminimis` | boolean | Indicates if the rate applies under de minimis thresholds |

### FreeTradeAgreementRate

| Property | Type | Description |
|---|---|---|
| `ftaName` | string | The FTA Name |
| `ftaRate` | Rate |  |

### RestrictionsModel

| Property | Type | Description |
|---|---|---|
| `type` | string | The unique ID number for the quote |
| `regulation` | string | The regulation for the quote |
| `complianceMessage` | string | The compliance for the quote |
| `condition` | string | The condition for the quote |
| `hsCode` | string | The hsCode for the quote |
| `governmentAgency` | string | The government agency for the quote |
| `pgaCode` | string | The pgaCode for the quote |
| `exportCode` | string | The exportCode for the quote |
| `programCode` | string | The programCode for the quote |
| `agencyCode` | string | The agencyCode for the quote |
| `flagNote` | string | The flagNote for the quote |
| `ruleTitle` | string | The ruleTitle for the quote |
| `ruleSummary` | string | The ruleSummary for the quote |
| `searchKeyword` | string | The searchKeyword for the quote |
| `legislationTitle` | string | The legislationTitle for the quote |
| `legislationSummary` | string | The legislationSummary for the quote |
| `textLink` | string | The textLink for the quote |
| `webLink` | string | The webLink for the quote |
| `topic` | string | The topic for the quote |

### ErrorInfo

| Property | Type | Description |
|---|---|---|
| `code` | string | Name of the error. Refer to Error Codes section for a list of accepted values. |
| `message` | string | Short one-line message to summarize what went wrong |
| `target` | string | What object or service caused the error? (Unknown, HttpRequest, HttpRequestHeaders, IncorrectData) |
| `details` | array | Array of detailed error messages |

### ErrorDetail

| Property | Type | Description |
|---|---|---|
| `code` | string | Name of the error. Refer to Error Codes section for a list of accepted values. |
| `number` | integer | Unique ID number referring to this error or message. |
| `message` | string | Concise summary of the message, suitable for display in the caption of an alert box. |
| `description` | string | A more detailed description of the problem referenced by this error message, suitable for display in the contents area of an alert box. |
| `helpLink` | string | URL to help for this message |
| `refersTo` | string | Item the message refers to, if applicable. This is used to indicate a missing or incorrect value. |
| `severity` | string | Severity of the message`:`  Success, Warning, Error and Exception. |

### HsValidCodeRequest

| Property | Type | Description |
|---|---|---|
| `hsCode` | string |  |
| `country` | string |  |
| `version` | string |  |
| `isExport` | boolean |  |

### HsValidCodeResponse

| Property | Type | Description |
|---|---|---|
| `hsCode` | string |  |
| `country` | string |  |
| `isValid` | boolean |  |
| `validatedOn` | string |  |
| `validUntil` | string |  |
| `updatedOn` | string |  |
| `message` | string |  |

### ErrorResponse

| Property | Type | Description |
|---|---|---|
| `errorCode` | string |  |
| `message` | string |  |

### HsCodeVerificationRequest

| Property | Type | Description |
|---|---|---|
| `hsCode` | string | The HS code to verify. Must be 6-12 digits, optionally followed by up to 2 letters. |
| `classification` | HSClassificationModel |  |

### HsCodeVerificationResponse

| Property | Type | Description |
|---|---|---|
| `verified` | boolean | Whether the HS code was verified as appropriate for the product |
| `providedHsCode` | string | Echo of the HS code that was submitted for verification |
| `classification` | object |  |
| `message` | string | Human-readable message about the verification result |
