# Ecommerce Connectors

Upload and manage product catalogs via ecommerce connectors. Supports single-file
uploads (up to 99 MB) and multipart uploads for larger catalogs.


## Upload a product catalog

 - [POST /ecommerce/connectors/{id}/catalog](https://developers.intercom.com/docs/references/preview/rest-api/api.intercom.io/ecommerce-connectors/uploadecommercecatalog.md): Upload a product catalog to an ecommerce connector. The catalog must be a JSON
array of product objects. There are two upload modes:

Single-file upload — POST a single catalog file (up to 99 MB per request).
Omit finalize and import_job_id. Returns 202 Accepted when sync has started.

Multipart upload — For catalogs that must be split across multiple requests:

1. POST the first part with finalize=false (no import_job_id). The response
   returns an import_job_id and next_part_number.
2. POST each subsequent part with finalize=false, the import_job_id from step 1,
   and the part_number from the previous response. Each part must be ≤ 99 MB.
3. POST with finalize=true and the import_job_id to complete the upload and
   start the sync. No catalog file is required in the finalization request.

Part uploads are idempotent — retrying the same part_number does not create
a duplicate. If a response is lost, retry with the same part_number.

## Product object structure

The catalog file must be a JSON array where each element is a product object.
Only id, title, and url are required — all other fields are optional.

| Field | Type | Required | Description |
|---|---|---|---|
| id | string | ✓ | Your unique product identifier. Used to match products on re-upload so only changed products are re-indexed. Also the delete key — any product ID absent from a new upload is removed from Fin's knowledge. Must be stable across uploads. |
| title | string | ✓ | Product name. Used by Fin when searching for and recommending products. |
| url | string | ✓ | Canonical product page URL shown in Fin's product recommendations. Must be a valid https:// URL. |
| description | string | | Product description that Fin reads to understand what the product is. HTML formatting is supported and safely sanitized (description_html takes precedence if both are provided). This is the primary field Fin uses to match products to shopper questions — a richer description leads to better recommendations. |
| featured_image_url | string | | Primary product image shown in Fin's recommendation cards. Falls back to the first entry of image_urls if not provided. If no valid image can be resolved for a variant, that variant's card is not shown to the shopper. |
| image_urls | string[] | | Additional product images. Used as a fallback when featured_image_url is absent or when a variant has no specific image. |
| price_min | number | | Lowest price across all variants. If omitted, derived automatically from variant prices. Fin uses this to filter products when a shopper mentions a budget (e.g. "under $100"). Displayed as a range alongside price_max, or as a single value if both are equal. |
| price_max | number | | Highest price across all variants. If omitted, derived from variant prices. Used alongside price_min for budget filtering and price display. |
| currency | string | | ISO 4217 currency code (e.g. "USD", "EUR", "GBP"). Defaults to USD if omitted. Used to format prices with the correct symbol in Fin's responses and product cards. |
| in_stock | boolean | | Whether the product is available to purchase. If omitted, derived from variant stock — the product is in stock if at least one variant has in_stock: true. Products with no in-stock variants are hidden from Fin entirely. |
| category_path | string or string[] | Strongly recommended | Hierarchical category breadcrumb (e.g. ["Clothing", "Outerwear", "Jackets"]). Fin understands the hierarchy — a shopper asking about "Clothing" sees products from all subcategories underneath it. The most specific category is shown in search results. |
| collections | string[] | Strongly recommended | Collections or groupings this product belongs to in your store. Fin uses collections to understand your catalog's structure and answer questions like "what's in the sale collection?". |
| tags | string[] | | Free-form keywords matching how shoppers phrase needs in chat (e.g. ["waterproof", "gift", "plus-size"]). Complements category_path and collections. |
| available_options | object[] | | Option types and their possible values (e.g. {"name": "Size", "values": ["S", "M", "L"]}). Fin uses these to understand what choices a shopper can make and to correctly filter variants when asked for a specific size, colour, or other attribute. |
| additional_data | object | | Custom attributes for your business. Fin uses these to show each customer only relevant products. All keys must be consistent across all products in your catalog — the attribute schema is read from the first product in the file. |
| variants | object[] | | Individual purchasable variants. Fin recommends specific variants (not just products), so populating variants with accurate stock, price, and option data leads to more precise recommendations. See the variant table below. |

### Variant object structure

Each object in the variants array may contain:

| Field | Type | Required | Description |
|---|---|---|---|
| id | string | ✓ | Unique identifier for this variant within the product. |
| title | string | | Variant display name shown to shoppers (e.g. "Small / Blue"). |
| price | number | | Price of this specific variant. Fin uses variant prices for precise budget filtering and displays the variant price in recommendation cards. |
| compare_at_price | number | | Original price before a discount. When provided, Fin will naturally mention the saving (e.g. "down from $129 to $99"). |
| in_stock | boolean | | Whether this variant is currently available. Out-of-stock variants are not shown in Fin's recommendation cards and Fin will not suggest them to shoppers. |
| image_url | string | | Image specific to this variant. Takes precedence over the product's featured_image_url. Falls back to featured_image_url, then image_urls. If no valid image can be resolved, this variant's recommendation card will not be shown. |
| selected_options | object[] | | The specific option values that define this variant (e.g. [{"name": "Size", "value": "Small"}, {"name": "Color", "value": "Blue"}]). Fin uses these to match shopper requests like "do you have this in medium?" to the correct variant. |
| url | string | | Direct link to this variant's page. Takes precedence over the product URL in recommendation cards. If omitted, constructed automatically as {product_url}?variant={id}. |

### Example catalog file

json
[
  {
    "id": "prod-12345",
    "title": "Classic Cotton T-Shirt",
    "url": "https://example.com/products/classic-cotton-t-shirt",
    "description": "A comfortable everyday t-shirt.",
    "featured_image_url": "https://cdn.example.com/images/t-shirt.jpg",
    "price_min": 19.99,
    "price_max": 29.99,
    "currency": "USD",
    "in_stock": true,
    "tags": ["organic", "bestseller"],
    "collections": ["Summer Collection"],
    "category_path": "Clothing > T-Shirts",
    "available_options": [
      {"name": "Size", "values": ["S", "M", "L"]},
      {"name": "Color", "values": ["White", "Blue"]}
    ],
    "variants": [
      {
        "id": "var-001",
        "title": "S / White",
        "price": 19.99,
        "in_stock": true,
        "selected_options": [
          {"name": "Size", "value": "S"},
          {"name": "Color", "value": "White"}
        ]
      },
      {
        "id": "var-002",
        "title": "M / Blue",
        "price": 29.99,
        "in_stock": true,
        "selected_options": [
          {"name": "Size", "value": "M"},
          {"name": "Color", "value": "Blue"}
        ]
      }
    ],
    "additional_data": {
      "sku": "TSHIRT-WHT-S",
      "vendor": "Acme Apparel"
    }
  }
]

