# 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.

 **Unify endpoint**:
 The `/api/v2/companies/{companyId}/classifications` resource (POST/GET) is the
 unify, explicit-intent contract. Callers declare what they want via
 `classificationType` (`managed`, `autoPro`, `autoEssentials`), `classifications`,
 and `classificationModifiers`, instead of relying on the implicit Auto HS
 branching of the older `/classifications/hs` endpoints. It uses Bearer (OAuth 2.0)
 authentication and the AvaTax error envelope. See
 `documentation/design/unified endpoint/` for background.

Source: https://developer.avalara.com/products/item-classification/api/

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

---

## Endpoints

### Classifications

#### Submit a unified classification request

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

Accepts three body shapes:
1. Single object with `item`.
2. Single object with `items[]` sharing classification config.
3. Top-level JSON array of independent requests.

**Success responses** (`201 Created`, `207 Multi-Status`) are always `{ "items": [...] }`.

**HTTP-level errors** (`402`, `413`, `422`, `429`, `503`, `500`, and `401` from the gateway) return
the **AvaTax error envelope** (`AvaTaxError`) — `{ "error": { "code", "target", "details"[] } }` —
the same structural shape used for OAuth/gateway failures. Only **nested** rejections inside
a `207` item / per-COD result still use the small `{ "code", "message" }` object (`Error`).

**Parameters:**

| Name | Type | In | Required | Description |
|---|---|---|---|---|
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |

#### Retrieve a single classification by ID

`GET /api/v2/companies/{companyId}/classifications/{classificationId}`

Returns the unify view of a single classification by its composite
ID. The ID is the value previously returned in
`items[].classifications[].id` from `POST /classifications`
(e.g. `2-76713-1651708-CHEM-SAMPLE-008-HS_FULL-US`).

Internally the controller delegates to `UnifyGetService`, which
mirrors the legacy V1 GET pipeline: token check, SKU mapping
lookup, cross-customer guard, customer access checks, then
`ClassificationService.getClassification(...)`. The legacy
result is then reshaped into `ClassificationGetResponse` with
the unify field-name flips reversed automatically.

## Error envelope by HTTP status

| Status | Envelope        | Trigger                                                                                  |
|--------|-----------------|------------------------------------------------------------------------------------------|
| 200    | `ClassificationGetResponse` | Classification found.                                                        |
| 401    | `AvaTaxError`   | Gateway authentication failure (rejected before the controller ran).                     |
| 404    | `AvaTaxError`   | `SkuMappingNotFound` OR underlying classification null OR downstream `AvaTaxException`.  |
| 422    | `AvaTaxError`   | `ErrorCodeException` (auth / company-id / customer access). Same envelope as V1 GET.     |
| 500    | `AvaTaxError`   | Unhandled exception — same envelope as `POST .../classifications` (`UnhandledException`).  |

**Parameters:**

| Name | Type | In | Required | Description |
|---|---|---|---|---|
| `undefined` |  |  | No |  |
| `classificationId` | string | path | Yes | Composite classification ID returned by the POST endpoint
(e.g. `2-76713-1651708-CHEM-SAMPLE-008-HS_FULL-US`). Treat
it as opaque on the client - the server resolves it through
the SKU mapping store, not by parsing segments. |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |
| `undefined` |  |  | No |  |


### 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 |

### ClassificationRequest

| Property | Type | Description |
|---|---|---|
| `classificationType` | string |  |
| `classifications` | array |  |
| `classificationModifiers` | ClassificationModifiers |  |
| `countryOfDestination` | array | Capped at 10 per request (configurable via
unify.max.countries.of.destination). Exceeding returns 413. |
| `providedHsCodes` | object |  |
| `hsCodeTest` | object | **Sandbox / integration use only.** Pre-supplied HS code per
country of destination. When present, the server treats the
listed code as the final classification for that COD and
bypasses all classification logic (no Indix / HSAC call).
Strictly capped to 20 characters per value.

Independent of `classificationType`, every COD listed in
`hsCodeTest` is processed via the managed pipeline. When the
caller asked for an auto type and supplied `hsCodeTest` for
every entry in `countryOfDestination`, the entire request is
re-routed to managed. Partial coverage splits the request:
covered CODs run through managed, the rest through the
requested auto path.

Covered CODs surface in the response as
`status: "classified"`, `hsCode: ""`,
`confidence: "test"`. Uncovered CODs follow the regular auto
response shape. The response's `classificationType` echoes
the original caller value (re-routing is internal). |
| `complianceData` | ComplianceData |  |
| `item` | Item |  |
| `items` | array | Bulk shape. Capped at 10 per request (configurable via
unify.max.items.per.request). Exceeding returns 413. |

### ClassificationModifiers

| Property | Type | Description |
|---|---|---|
| `broker` | boolean |  |
| `mtccPlus` | boolean |  |
| `reclassify` | boolean |  |
| `verify` | boolean |  |
| `autoPerformance` | string |  |
| `priority` | integer |  |

### ComplianceData

Pure pass-through map. Anything the caller puts here is forwarded
verbatim to the Quoting compliance service. The only locally
validated fields are `startDate` / `endDate` (yyyy-MM-dd, end >=
start). System-managed keys (`id`, `hscode`, `countryOfImport`,
`countryOfExport`, `countryOfManufacture`, `section232Parameters`)
are silently stripped before forwarding. Section 232 must be sent
via `item.section232[]`.

| Property | Type | Description |
|---|---|---|
| `startDate` | string |  |
| `endDate` | string |  |

### Item

| Property | Type | Description |
|---|---|---|
| `companyId` | integer |  |
| `itemCode` | string |  |
| `parentCode` | string |  |
| `title` | string |  |
| `description` | string |  |
| `category` | string |  |
| `url` | string |  |
| `imageUrl` | string |  |
| `material` | string |  |
| `countryOfOrigin` | string |  |
| `countryOfExport` | string |  |
| `hsHint` | string |  |
| `taxCode` | string |  |
| `job` | string |  |
| `measurements` | Measurements |  |
| `identifiers` | Identifiers |  |
| `manufacturer` | Manufacturer |  |
| `section232` | array |  |
| `attributes` | object |  |

### Measurements

| Property | Type | Description |
|---|---|---|
| `price` | string | " " |
| `weight` | string | " " (lb|oz|kg|g) |
| `length` | string | " " (in|cm|m|mm) |
| `width` | string |  |
| `height` | string |  |

### Identifiers

| Property | Type | Description |
|---|---|---|
| `gtin` | string |  |
| `upc` | string |  |
| `ean` | string |  |
| `mpn` | string |  |
| `asin` | string |  |
| `jan` | string |  |
| `isbn` | string |  |
| `cas` | string |  |
| `ebayEpid` | string |  |
| `ebayItemId` | string |  |

### Manufacturer

| Property | Type | Description |
|---|---|---|
| `manufacturerName` | string |  |
| `countryOfManufacture` | string |  |

### Section232Entry

| Property | Type | Description |
|---|---|---|
| `material` | string |  |
| `percentage` | number |  |
| `countryOfOrigin` | string |  |

### ClassificationResponse

| Property | Type | Description |
|---|---|---|
| `items` | array |  |

### ItemResult

| Property | Type | Description |
|---|---|---|
| `itemCode` | string |  |
| `companyId` | integer |  |
| `status` | string |  |
| `classificationType` | string |  |
| `error` | Error |  |
| `classifications` | array |  |

### ClassificationResult

| Property | Type | Description |
|---|---|---|
| `id` | string |  |
| `activity` | string |  |
| `countryOfDestination` | string |  |
| `countryOfExport` | string |  |
| `enrichments` | array |  |
| `classificationModifiers` | ClassificationModifiers |  |
| `status` | string |  |
| `hsCode` | string |  |
| `confidence` | string |  |
| `verifyResult` | string |  |
| `providedHsCode` | string |  |
| `message` | string |  |
| `compliance` | array | Per-COD compliance payload returned by the Quoting service. Populated only
when `compliance` is in `classifications` *and* an HS code is available
for the COD (auto path: Indix prediction; managed path:
caller-supplied `providedHsCodes`). Mutually exclusive with
`complianceError`. Item shape mirrors
`com.avalara.xb.classification.views.Compliance` (Quoting response). |
| `complianceError` | object | Set when the unify compliance gate skipped the Quoting call because the item
is missing a field Quoting requires (today: `countryOfExport`). Wire
shape is identical to Quoting's own `ValueRequiredError` payload
(`{ details: [{ code, number, message, description, helpLink, severity }] }`).
Mutually exclusive with `compliance`; the classification itself is
unaffected. |
| `error` | Error |  |

### ClassificationGetResponse

Unify GET response - one classification record identified by the
composite `id`, with the originating item embedded as `item`.
Field projection is driven by the legacy classification record
loaded from the underlying store (HSCT / ItemMaster / DW /
parking lot, in priority order), not by parsing the ID. Fields
beyond `id` / `status` are populated when the legacy record
carries them. The embedded `item` reverses the legacy
field-name flips (`description` -> `title`, `summary` ->
`description`, `itemGroup` -> `category`); the
`_uncategorized` sentinel is silently dropped.

| Property | Type | Description |
|---|---|---|
| `id` | string | Composite ID; same value the POST response surfaces under `items[].classifications[].id`. |
| `activity` | string | Reverse-mapped from the legacy uppercase activity (`HS_FULL` -> `hsFull`, etc.). |
| `classificationType` | string |  |
| `countryOfDestination` | string | Present for `hsFull` / `hs6`. |
| `countryOfExport` | string | Present for `export`. |
| `enrichments` | array |  |
| `classificationModifiers` | ClassificationModifiers |  |
| `status` | string | Reverse-mapped from the legacy status using the same heuristics as the POST builder. |
| `hsCode` | string | Final HS code; present once `status == "classified"` for `hsFull` / `hs6`. |
| `confidence` | string | Suppressed when the resolved customer's `confidenceFlag` is off. |
| `confidenceDescription` | string | Suppressed alongside `confidence` for customers without the confidence flag. |
| `rationale` | string | Suppressed unless `status == "classified"` (V1 parity). |
| `item` | Item |  |

### Error

Small `{ "code", "message" }` object used **only** inside successful HTTP responses
for **nested** failures — e.g. `207` payloads under `items[].error` or
`items[].classifications[].error` when a single item or COD is rejected.

**Not** used for HTTP-level `402` / `413` / `422` / `503` / `500` on `POST .../classifications`;
those responses use `AvaTaxError`. Gateway `401` also uses `AvaTaxError`.

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

### ComplianceError

Compliance-enrichment error envelope returned on
`ClassificationResult.complianceError` when the unify compliance gate
short-circuited the Quoting call. Wire shape is identical to
Quoting's own `{ details: [...] }` validation-error payload, so
unify callers can reuse the error handling they already wrote for
direct AvaTax / Quoting calls. Mutually exclusive with
`ClassificationResult.compliance`.

| Property | Type | Description |
|---|---|---|
| `code` | string | Optional top-level summary code. Omitted by the unify gate today. |
| `message` | string | Optional top-level summary message. Omitted by the unify gate today. |
| `target` | string | Optional context tag. Omitted by the unify gate today. |
| `details` | array |  |

### ComplianceErrorDetail

Single entry inside `ComplianceError.details[]`. 1:1 mirror of the
AvaTax `ErrorDetail` shape (minus the legacy `faultCode` slot). The
unify gate emits `{ code: "ValueRequiredError", number: 5 }` for
required-field violations - byte-for-byte identical to what Quoting
returns when called directly.

| Property | Type | Description |
|---|---|---|
| `code` | string |  |
| `number` | integer |  |
| `message` | string |  |
| `description` | string |  |
| `helpLink` | string |  |
| `severity` | string |  |

### AvaTaxError

AvaTax-style error envelope `{ "error": { "code", "target", "details"[] } }`.

Returned for:
- Gateway / OAuth failures (**401**) before the controller runs.
- **POST** `/{companyId}/classifications` HTTP-level failures: **402**, **413**, **422**,
  **503**, **500** (and downstream `AvaTaxException` bodies when mapped by the controller).
- **GET** `.../classifications/{id}` **404**, **422**, **500** (mirrors legacy V1).

Nested per-item / per-COD errors inside a **207** `ClassificationResponse` still use the flat
`Error` schema on the embedded `error` fields.

Use `error.code` plus `error.details[].number` to branch programmatically. Common numbers
include `31` / `34` / `37` (auth), `5` (`ValueRequiredError`), `50` (`UnhandledException`),
`70` (`ModelStateInvalid`), `3011` (`MtccPlusNotProvisioned`), `3015` (`EntitlementRequired`),
`3016` (`PayloadTooLarge`), `3008` (`RetryRequest`), and values from `ClassificationError`.

| Property | Type | Description |
|---|---|---|
| `error` | object |  |

### AvaTaxErrorDetail

| Property | Type | Description |
|---|---|---|
| `code` | string |  |
| `number` | integer |  |
| `message` | string |  |
| `description` | string |  |
| `helpLink` | string |  |
| `severity` | string |  |
