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

# Upload a product catalog

> Uploads a JSON file containing a product catalog.

To update the product catalog, upload a file with the updated product data. A new upload overwrites the current product catalog.

<Expandable title="product fields and JSON example">
  <ResponseField name="id" type="string" required>
    Unique product identifier.
  </ResponseField>

  <ResponseField name="title" type="string" required>
    The product name.
  </ResponseField>

  <ResponseField name="description" type="string" required>
    The product description.
  </ResponseField>

  <ResponseField name="url" type="string" required>
    The product URL.
  </ResponseField>

  <ResponseField name="currency" type="string" required>
    The currency code applied to all variant prices (e.g. `USD`).
  </ResponseField>

  <ResponseField name="categories" type="string[]" required>
    At least one category.
  </ResponseField>

  <ResponseField name="tags" type="string[]">
    Free-form tags.
  </ResponseField>

  <ResponseField name="images" type="object[]" required>
    At least one image.

    <Expandable title="image fields">
      <ResponseField name="url" type="string" required>
        The image URL.
      </ResponseField>

      <ResponseField name="alt_text" type="string">
        Alternative text for the image.
      </ResponseField>
    </Expandable>
  </ResponseField>

  <ResponseField name="attributes" type="object[]" required>
    At least one `{key, value}` pair. More meaningful attributes produce better search results for the AI agent.

    <Expandable title="attribute fields">
      <ResponseField name="key" type="string" required>
        The attribute name.
      </ResponseField>

      <ResponseField name="value" type="string | number" required>
        The attribute value.
      </ResponseField>
    </Expandable>
  </ResponseField>

  <ResponseField name="variants" type="object[]" required>
    At least one variant.

    <Expandable title="variant fields">
      <ResponseField name="id" type="string" required>
        Unique variant identifier.
      </ResponseField>

      <ResponseField name="title" type="string">
        The variant name.
      </ResponseField>

      <ResponseField name="sku" type="string">
        The variant SKU.
      </ResponseField>

      <ResponseField name="options" type="object">
        A key-value map of variant option names to values (e.g. `{"color": "blue"}`).
      </ResponseField>

      <ResponseField name="available" type="boolean" required>
        If `true`: the variant is available for purchase.
      </ResponseField>

      <ResponseField name="price" type="number" required>
        The variant price.
      </ResponseField>
    </Expandable>
  </ResponseField>

  ```json products.json
  [
    {
      "id": "product-001",
      "title": "Product title",
      "description": "Product description",
      "url": "https://example.com/product-001",
      "currency": "USD",
      "categories": ["electronics", "audio"],
      "tags": ["bestseller"],
      "images": [
        { "url": "https://example.com/image_1.jpg", "alt_text": "Front view" },
        { "url": "https://example.com/image_2.jpg" }
      ],
      "attributes": [
        { "key": "color", "value": "blue" },
        { "key": "brand", "value": "Acme" }
      ],
      "variants": [
        {
          "id": "product-001-blue-l",
          "title": "Blue / L",
          "sku": "ACME-BL-L",
          "options": { "color": "blue", "size": "L" },
          "available": true,
          "price": 49.99
        }
      ]
    }
  ]
  ```
</Expandable>


## OpenAPI

````yaml /api/product-directory/openapi.json post /v1/catalogs/imports
openapi: 3.0.0
info:
  title: Product Directory API
  description: >-
    A service for uploading and managing a product catalog for use by an AI
    agent.
  version: 1.0.0
servers:
  - url: https://api.text.com/product-directory
    description: Main production server URL
security:
  - PersonalAccessToken: []
paths:
  /v1/catalogs/imports:
    post:
      tags:
        - Catalog
      summary: Upload a product catalog
      description: >-
        Uploads a JSON file containing a product catalog.


        To update the product catalog, upload a file with the updated product
        data. A new upload overwrites the current product catalog.
      operationId: upload-a-product-catalog
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UploadCatalogRequest'
      responses:
        '202':
          description: >-
            The catalog import job was queued. A `202` response doesn't mean the
            products passed validation — invalid products are skipped and
            counted in `failed_count` on the job status; they aren't rejected at
            upload time.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UploadCatalogResponse'
              example:
                job_id: 550e8400-e29b-41d4-a716-446655440000
        '401':
          description: Missing or invalid token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: authentication
                  message: No Authorization header.
        '413':
          description: The file exceeds the 50MB request size limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: entity_too_large
                  message: max_file_size_exceeded
        '422':
          description: The file isn't valid, or its filename doesn't end in `.json`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalid_file:
                  summary: File isn't valid JSON, or isn't a non-empty JSON array
                  value:
                    error:
                      type: validation
                      message: invalid_file
                unsupported_format:
                  summary: Filename doesn't end in .json
                  value:
                    error:
                      type: validation
                      message: unsupported_format
components:
  schemas:
    UploadCatalogRequest:
      type: object
      required:
        - file
      properties:
        file:
          type: string
          format: binary
          description: >-
            A JSON file containing an array of product objects. The filename
            must end in `.json`. Maximum size: 50MB. The file is processed
            asynchronously — the response includes a `job_id` for tracking
            progress with [Check import
            status](/api/product-directory/catalog/check-import-status).
    UploadCatalogResponse:
      type: object
      required:
        - job_id
      properties:
        job_id:
          type: string
          format: uuid
          description: Unique import job identifier. Use it to poll `Check import status`.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - message
          properties:
            type:
              type: string
              description: The error category.
            message:
              type: string
              description: A message describing the error.
  securitySchemes:
    PersonalAccessToken:
      description: >-
        Use your `account ID` as the username and your personal access token
        (PAT) as the password, or pass a Base64-encoded value directly in the
        Authorization header. For more information, see the <a
        href="/authentication/personal-access-tokens">personal access tokens
        guide</a>.
      type: http
      scheme: basic

````