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

# Upload a catalog artifact

> Uploads a catalog CSV as multipart form data and returns an `artifact_id` for use when starting an optimization workflow.

The HTTP client must set the `Content-Type: multipart/form-data` header with the appropriate boundary; the header should not be set manually. The `domain` header is required and must be a brand domain (for example, `vessel.com`) that the authenticated principal is authorized to access.

Each request creates a new artifact, even when the file content is identical to a previously uploaded file. Retain the returned `artifact_id` for the workflow that will reference it.

For catalogs larger than approximately 100 MB, contact fabric support to enable the presigned-URL upload flow.

### Catalog CSV format

The uploaded file must be UTF-8 encoded, comma-delimited, and include a header row. The supported columns are:

| Column               | Required    | Description |
| :------------------- | :---------- | :---------- |
| `title`              | Yes         | Product display name as shown on the product detail page. |
| `sku`                | Yes         | Unique product identifier within the brand catalog. |
| `description`        | Yes         | Full product description from the product detail page. |
| `category_id`        | Conditional | The brand's category identifier. Each row must provide either `category_id` or `breadcrumb`. |
| `breadcrumb`         | Conditional | Full category hierarchy separated by ` > ` (for example, `Mens > Clothing > Pants`). Each row must provide either `breadcrumb` or `category_id`. |
| `category`           | No          | Free-text category label. Used as a hint when neither `category_id` nor `breadcrumb` resolves to a known category. |
| `product_group_id`   | No          | Identifier shared by product variants that belong to the same family. |
| `price`              | No          | Numeric price value for the product. |
| `currency`           | No          | Currency code corresponding to `price`. |
| `url`                | No          | Canonical product detail page URL. |
| `images`             | No          | One or more image URLs separated by the pipe character (`\|`). |
| `attribute.<name>`   | No          | Custom attribute value. Free-form string, single value per cell. The `<name>` segment must match an attribute key configured for the brand. |

For a worked end-to-end example including auth and workflow creation, see the [Product Import Developer Guide](/product-agent/developer-guides/postman-import-csv-guide).




## OpenAPI

````yaml product-agent.openapi post /v2/optimize/artifacts
openapi: 3.0.1
info:
  contact:
    email: support@fabric.inc
    name: fabric Support Team
  description: >
    The Product Agent API helps brands optimize product data for AI-driven
    commerce.

    Monitor how your catalog performs in AI search experiences, enrich product

    content for stronger semantic visibility, and publish optimized data across

    channels. Designed for iterative improvement, Product Agent enables teams to

    measure, refine, and enhance product content as AI shopping behavior
    evolves.
  license:
    name: fabric API License
    url: https://fabric.inc/api-license
  termsOfService: https://fabric.inc/terms-of-use
  title: fabric Orders API
  version: 3.0.0
  x-audience: external-public
servers:
  - url: https://commerceos.aiagents.fabric.inc/api
    description: Production API
security:
  - authorization: []
externalDocs:
  description: Find out more about Product Agent.
  url: https://developer.fabric.inc/product-agent/overview
paths:
  /v2/optimize/artifacts:
    post:
      summary: Upload a catalog artifact
      description: >
        Uploads a catalog CSV as multipart form data and returns an
        `artifact_id` for use when starting an optimization workflow.


        The HTTP client must set the `Content-Type: multipart/form-data` header
        with the appropriate boundary; the header should not be set manually.
        The `domain` header is required and must be a brand domain (for example,
        `vessel.com`) that the authenticated principal is authorized to access.


        Each request creates a new artifact, even when the file content is
        identical to a previously uploaded file. Retain the returned
        `artifact_id` for the workflow that will reference it.


        For catalogs larger than approximately 100 MB, contact fabric support to
        enable the presigned-URL upload flow.


        ### Catalog CSV format


        The uploaded file must be UTF-8 encoded, comma-delimited, and include a
        header row. The supported columns are:


        | Column               | Required    | Description |

        | :------------------- | :---------- | :---------- |

        | `title`              | Yes         | Product display name as shown on
        the product detail page. |

        | `sku`                | Yes         | Unique product identifier within
        the brand catalog. |

        | `description`        | Yes         | Full product description from the
        product detail page. |

        | `category_id`        | Conditional | The brand's category identifier.
        Each row must provide either `category_id` or `breadcrumb`. |

        | `breadcrumb`         | Conditional | Full category hierarchy separated
        by ` > ` (for example, `Mens > Clothing > Pants`). Each row must provide
        either `breadcrumb` or `category_id`. |

        | `category`           | No          | Free-text category label. Used as
        a hint when neither `category_id` nor `breadcrumb` resolves to a known
        category. |

        | `product_group_id`   | No          | Identifier shared by product
        variants that belong to the same family. |

        | `price`              | No          | Numeric price value for the
        product. |

        | `currency`           | No          | Currency code corresponding to
        `price`. |

        | `url`                | No          | Canonical product detail page
        URL. |

        | `images`             | No          | One or more image URLs separated
        by the pipe character (`\|`). |

        | `attribute.<name>`   | No          | Custom attribute value. Free-form
        string, single value per cell. The `<name>` segment must match an
        attribute key configured for the brand. |


        For a worked end-to-end example including auth and workflow creation,
        see the [Product Import Developer
        Guide](/product-agent/developer-guides/postman-import-csv-guide).
      operationId: uploadOptimizeArtifact
      parameters:
        - $ref: '#/components/parameters/DomainHeader'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/UploadArtifactRequest'
      responses:
        '201':
          description: Artifact uploaded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ArtifactResponse'
              example:
                artifact_id: art_95c650ded4824dc79bb6df16427e4a10
                kind: csv
                source: upload
                bytes: 45678
                sha256: >-
                  9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
                content_type: text/csv
                uri: >-
                  s3://product-agent-data-prod-ue2/optimize-artifacts/svc_yourClientId/art_95c650ded4824dc79bb6df16427e4a10/catalog.csv
                original_filename: catalog.csv
                brand_id: 691df5949676c8e0b1d7b6b3
                created_at: '2026-05-15T10:30:00Z'
        '401':
          description: Unauthorized. The access token is missing or has expired.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/errorResponse'
        '403':
          description: >-
            Forbidden. The caller is not authorized for the brand specified in
            the `domain` header.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/errorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/errorResponse'
      security:
        - bearerAuth: []
components:
  parameters:
    DomainHeader:
      name: domain
      in: header
      required: true
      schema:
        type: string
        example: vessel.com
      description: >-
        The brand domain name (for example, `vessel.com` or
        `containerstore.com`) used to scope the request to a specific brand's
        data and configuration. The authenticated principal must be authorized
        for the specified brand.
  schemas:
    UploadArtifactRequest:
      type: object
      required:
        - file
      properties:
        file:
          type: string
          format: binary
          description: The catalog file to upload. The file must be a CSV.
        kind:
          allOf:
            - $ref: '#/components/schemas/ArtifactKind'
          nullable: true
          description: >-
            Optional. When omitted, the server infers the kind from the filename
            extension or content type. The supported value is `csv`.
    ArtifactResponse:
      type: object
      required:
        - artifact_id
        - kind
        - source
        - content_type
        - uri
        - brand_id
        - created_at
      properties:
        artifact_id:
          type: string
          description: >-
            Stable identifier for the artifact. Reference this value when
            creating a workflow.
          example: art_95c650ded4824dc79bb6df16427e4a10
        kind:
          $ref: '#/components/schemas/ArtifactKind'
        source:
          $ref: '#/components/schemas/ArtifactSource'
        bytes:
          type: integer
          nullable: true
          description: File size in bytes.
          example: 45678
        sha256:
          type: string
          nullable: true
          description: Hex-encoded SHA-256 checksum of the file contents.
          example: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
        content_type:
          type: string
          description: MIME type as detected by the server.
          example: text/csv
        uri:
          type: string
          description: Internal storage URI for the artifact. Informational only.
          example: >-
            s3://product-agent-data-prod-ue2/optimize-artifacts/svc_yourClientId/art_95c650ded4824dc79bb6df16427e4a10/catalog.csv
        original_filename:
          type: string
          nullable: true
          description: The filename submitted with the multipart upload.
          example: catalog.csv
        brand_id:
          type: string
          description: >-
            The brand the artifact is associated with, derived from the `domain`
            header.
          example: 691df5949676c8e0b1d7b6b3
        created_at:
          type: string
          format: date-time
          description: Upload timestamp in UTC.
          example: '2026-05-15T10:30:00Z'
    errorResponse:
      description: Error response
      properties:
        errors:
          description: Errors
          items:
            $ref: '#/components/schemas/errorResponse'
          type: array
        message:
          description: Error message
          example: Bad request
          type: string
        type:
          description: Error type
          example: CLIENT_ERROR
          type: string
      type: object
    HTTPValidationError:
      type: object
      description: Validation error response body returned with HTTP 422.
      properties:
        detail:
          type: array
          items:
            $ref: '#/components/schemas/ValidationError'
    ArtifactKind:
      type: string
      enum:
        - csv
      description: Artifact file format. The supported value is `csv`.
    ArtifactSource:
      type: string
      enum:
        - upload
        - presigned
        - uri
        - generated
      description: >
        Indicates how the artifact was ingested. `upload` denotes a direct
        multipart upload, `presigned` denotes the presigned-URL flow used for
        large files, `uri` denotes a server-side fetch from an external URI, and
        `generated` denotes a system-produced artifact.
    ValidationError:
      type: object
      required:
        - loc
        - msg
        - type
      properties:
        loc:
          type: array
          items:
            oneOf:
              - type: string
              - type: integer
        msg:
          type: string
        type:
          type: string
  securitySchemes:
    authorization:
      bearerFormat: JWT
      scheme: bearer
      type: http

````