> ## Documentation Index
> Fetch the complete documentation index at: https://docs.numeral.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Classify Products

> Suggest a Numeral tax category for up to 20 products from their names and descriptions, using the AI provider keys stored for your account. Optionally create the classified products in one call. Available on API version 2026-01-01 and later.

## Classify Products Endpoint (2026-11-01)

Suggest a tax category for each product from its name and description, and optionally create the products in the same call. Every suggested category is a code from the [product categories](https://docs.numeral.com/essentials/product-categories.md) list, so the result can go straight into `POST /tax/products` or a calculation line item.

> [!WARNING]
>
> Product classification is in limited availability. Accounts that are not enabled receive a `404 ENDPOINT_NOT_FOUND` from this endpoint. Contact your Numeral representative to enable it.

> [!NOTE]
>
> Remember to include the `X-API-Version: 2026-11-01` header in your request to use this API version. This endpoint requires version `2026-01-01` or later.

### Before you call it

Classification runs on your own AI provider keys, not Numeral's. Store them in the dashboard under **Developers > Product Classification AI API Keys and Settings** before calling this endpoint. Test keys (`sk_test_...`) use the keys saved for the test environment and production keys use the production ones. A single OpenAI key is enough; Gemini and Anthropic keys are also supported. See the [product classification guide](https://docs.numeral.com/essentials/integration-guides/product-classification.md) for details.

### How to read a result

Each entry in `product_categories` has a `status`:

| `status` | `product_category` | `confidence_score` | Meaning |
| - | - | - | - |
| `classified` | A category code | `0` to `1` | A category was chosen. Review low scores before relying on them. |
| `fallback` | `GENERAL_MERCHANDISE` | `null` | No category could be chosen. Treat the suggestion as a placeholder. |
| `failed` | `null` | `null` | This product could not be processed. Retry it in a later batch. |

With `create_products: true`, `product_creation_status` reports what happened to each product record. Only `classified` products are created; `fallback` and `failed` products report `not_classified`. A product that already exists under the same `reference_product_id` is left unchanged and reports `already_exists`.

### Limits

* Up to 20 products per request.
* One classification request in flight per account. A second concurrent request gets `429` with a `Retry-After` header.
* A full batch can take tens of seconds, so allow at least 60 seconds for the response.

### Errors

| HTTP | `type` | When |
| - | - | - |
| 400 | `PRODUCT_CLASSIFICATION_CREDENTIALS_MISSING` | No AI provider keys are stored for this environment. |
| 400 | `PRODUCT_CLASSIFICATION_CREDENTIALS_INVALID` | The stored keys were rejected by the provider. Re-enter them in the dashboard. |
| 404 | `ENDPOINT_NOT_FOUND` | Product classification is not enabled for this account. |
| 429 | `PRODUCT_CLASSIFICATION_CAPACITY_EXCEEDED` | Another request is in progress for this account, or the service is at capacity. Retry after `Retry-After` seconds. |
| 429 | `PRODUCT_CLASSIFICATION_PROVIDER_QUOTA` | Your AI provider rate limited the request. Retry after `Retry-After` seconds. |
| 503 | `PRODUCT_CLASSIFICATION_UNAVAILABLE` | The service is temporarily unavailable, or every product in the batch failed. Retry with backoff. |


## OpenAPI

````yaml POST /tax/products/classify
openapi: 3.0.1
info:
  title: Numeral API
  description: >-
    API for sales tax calculations - Version 2026-01-01. This version introduces
    Merchant management and Platform Calculations for marketplace and payment
    processor scenarios.
  license:
    name: MIT
  version: '2026-01-01'
servers:
  - url: https://api.numeralhq.com/
security:
  - bearerAuth: []
paths:
  /tax/products/classify:
    post:
      summary: Classify Products
      description: >-
        Suggest a Numeral tax category for up to 20 products from their names
        and descriptions, using the AI provider keys stored for your account.
        Optionally create the classified products in one call. Available on API
        version 2026-01-01 and later.
      operationId: classifyProducts_v20260101
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductClassificationRequest'
        required: true
      responses:
        '200':
          description: One result per input product, in request order
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProductClassificationResponse'
        '400':
          description: >-
            Validation error, or no valid AI provider keys are stored for this
            environment (`PRODUCT_CLASSIFICATION_CREDENTIALS_MISSING`,
            `PRODUCT_CLASSIFICATION_CREDENTIALS_INVALID`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: >-
            Product classification is not enabled for this account
            (`ENDPOINT_NOT_FOUND`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: >-
            Another classification request is already in progress for this
            account, the service is at capacity, or your AI provider rate
            limited the request (`PRODUCT_CLASSIFICATION_CAPACITY_EXCEEDED`,
            `PRODUCT_CLASSIFICATION_PROVIDER_QUOTA`). Retry after the number of
            seconds in the `Retry-After` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: >-
            Product classification is temporarily unavailable
            (`PRODUCT_CLASSIFICATION_UNAVAILABLE`). Retry with backoff.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    ProductClassificationRequest:
      type: object
      properties:
        create_products:
          type: boolean
          default: false
          description: >-
            When true, every product that classifies successfully is also
            created with the suggested category, as if sent to `POST
            /tax/products`. Products already registered under the same
            `reference_product_id` are left unchanged. `reference_product_id`
            must then be unique within the batch.
          example: false
        products:
          type: array
          minItems: 1
          maxItems: 20
          description: Products to classify. Between 1 and 20 per request.
          items:
            $ref: '#/components/schemas/ProductClassificationInput'
      required:
        - products
    ProductClassificationResponse:
      type: object
      properties:
        object:
          type: string
          description: Always `list`.
          example: list
        create_products:
          type: boolean
          description: Echo of the request's `create_products`.
          example: false
        product_categories:
          type: array
          description: One result per input product, in the same order as the request.
          items:
            $ref: '#/components/schemas/ProductClassificationResult'
        testmode:
          type: boolean
          description: '`true` if called with a test API key.'
          example: true
      required:
        - object
        - create_products
        - product_categories
        - testmode
    Error:
      type: object
      description: Standard error response format for API version 2026-01-01
      properties:
        code:
          type: integer
          description: HTTP status code
          example: 400
        type:
          type: string
          description: Machine-readable error type
          example: MISSING_FIELD
        message:
          type: string
          description: Human-readable error message
          example: Required field 'address_country' is missing
      required:
        - code
        - type
        - message
    ProductClassificationInput:
      type: object
      properties:
        reference_product_id:
          type: string
          description: >-
            Your ID for the product. Returned unchanged on the matching result
            and used as the product ID when `create_products` is true. 1 to 255
            characters.
          example: sku-shirt-001
        reference_product_name:
          type: string
          description: >-
            The product name. The main input to classification. 1 to 255
            characters.
          example: Cotton crew neck t-shirt
        reference_product_description:
          type: string
          description: >-
            Optional product description. Improves classification for ambiguous
            names. Up to 255 characters.
          example: Unisex short-sleeve shirt, 100% cotton
      required:
        - reference_product_id
        - reference_product_name
    ProductClassificationResult:
      type: object
      properties:
        reference_product_id:
          type: string
          description: The `reference_product_id` from the matching input.
          example: sku-shirt-001
        status:
          type: string
          enum:
            - classified
            - fallback
            - failed
          description: >-
            `classified`: a category was chosen with a confidence score.
            `fallback`: no category could be chosen, so `GENERAL_MERCHANDISE` is
            suggested with no score. `failed`: this product could not be
            processed; retry it.
          example: classified
        product_category:
          type: string
          nullable: true
          description: >-
            The suggested category, always a code from the product categories
            list. `GENERAL_MERCHANDISE` when `status` is `fallback`, `null` when
            `failed`.
          example: CLOTHING_GENERAL
        confidence_score:
          type: number
          nullable: true
          minimum: 0
          maximum: 1
          description: >-
            How confident the classifier is in `product_category`, from 0 to 1.
            `null` unless `status` is `classified`.
          example: 0.94
        product_creation_status:
          type: string
          enum:
            - not_requested
            - created
            - already_exists
            - not_classified
            - failed
          description: >-
            What happened to the product record. `not_requested` when
            `create_products` is false. Otherwise `created`, `already_exists` (a
            product with this ID was already registered and was not changed),
            `not_classified` (status was `fallback` or `failed`, so nothing was
            created), or `failed` (classified, but the product could not be
            saved).
          example: not_requested
      required:
        - reference_product_id
        - status
        - product_category
        - confidence_score
        - product_creation_status
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.