Skip to main content
POST
/
api
/
v1
/
products
Upsert Products
curl --request POST \
  --url https://api.sequenzy.com/api/v1/products \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "products": [
    {}
  ],
  "products[].productId": "<string>",
  "products[].title": "<string>",
  "products[].description": "<string>",
  "products[].imageUrl": "<string>",
  "products[].url": "<string>",
  "products[].priceCents": 123,
  "products[].compareAtPriceCents": 123,
  "products[].currency": "<string>",
  "products[].inStock": true,
  "products[].variants": [
    {}
  ]
}
'
{
  "success": true,
  "upserted": 1,
  "backInStockEventsTriggered": 0,
  "products": [
    {
      "id": "prod_abc123",
      "productId": "SKU-PROTEIN-1KG",
      "provider": "api",
      "title": "Protein Powder",
      "priceCents": 8850,
      "currency": "USD",
      "inStock": true,
      "variants": [
        {
          "variantId": "SKU-PROTEIN-1KG-VANILLA",
          "title": "Vanilla",
          "priceCents": 8850,
          "inStock": true,
          "inventoryQuantity": 12
        }
      ]
    }
  ]
}
Create or update up to 100 products in your Sequenzy catalog, keyed by your productId. Products pushed here behave exactly like products synced from Shopify or WooCommerce - they power product blocks in emails, replenishment reminders, back-in-stock notifications, and segmentation. Use this endpoint to connect any e-commerce platform (custom checkout, CheckoutChamp, Sticky.io, your own backend) to Sequenzy. See the custom commerce integration guide for the full walkthrough. Updates are partial: optional fields you omit keep their stored values, so a stock-only update like {"productId": "SKU-1", "title": "...", "inStock": false} does not erase the product’s image, URL, or pricing. Pass an explicit null to clear a stored value.

Request Body

products
array
required
Products to create or update (1-100 per request). Each product is upserted by its productId.
products[].productId
string
required
Your product identifier. Used as the upsert key - pushing the same productId again updates the product.
products[].title
string
required
Product title.
products[].description
string
Product description.
products[].imageUrl
string
Product image URL.
products[].url
string
Public product page URL. Used for links in emails.
products[].priceCents
integer
Price in cents. Defaults to the lowest variant price when variants are provided.
products[].compareAtPriceCents
integer
Compare-at (strikethrough) price in cents.
products[].currency
string
ISO 4217 currency code (e.g. USD).
products[].inStock
boolean
Whether the product is in stock. Defaults to true, or to whether any variant is available when variants are provided.
products[].variants
array
Product variants. Each variant has variantId (required), title (required), sku, priceCents, compareAtPriceCents, imageUrl, inStock, inventoryQuantity, and options (array of { name, value }). When provided, the variant list is replaced entirely - pass an empty array to remove all variants. Omit the field to leave existing variants unchanged.
curl -X POST "https://api.sequenzy.com/api/v1/products" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "products": [
      {
        "productId": "SKU-PROTEIN-1KG",
        "title": "Protein Powder",
        "description": "Whey protein, 1kg bag",
        "imageUrl": "https://cdn.example.com/protein.jpg",
        "url": "https://store.example.com/products/protein",
        "currency": "USD",
        "variants": [
          {
            "variantId": "SKU-PROTEIN-1KG-VANILLA",
            "title": "Vanilla",
            "priceCents": 8850,
            "inventoryQuantity": 12,
            "options": [{ "name": "Flavor", "value": "Vanilla" }]
          },
          {
            "variantId": "SKU-PROTEIN-1KG-CHOC",
            "title": "Chocolate",
            "priceCents": 8850,
            "inStock": false,
            "options": [{ "name": "Flavor", "value": "Chocolate" }]
          }
        ]
      }
    ]
  }'

Stock Transitions

When an upsert changes a product or variant from out of stock to in stock, Sequenzy automatically fires the ecommerce.back_in_stock event for subscribers who requested a back-in-stock notification. Going out of stock cancels pending notifications. Replenishment settings configured in the dashboard are preserved across upserts.

Responses

{
  "success": true,
  "upserted": 1,
  "backInStockEventsTriggered": 0,
  "products": [
    {
      "id": "prod_abc123",
      "productId": "SKU-PROTEIN-1KG",
      "provider": "api",
      "title": "Protein Powder",
      "priceCents": 8850,
      "currency": "USD",
      "inStock": true,
      "variants": [
        {
          "variantId": "SKU-PROTEIN-1KG-VANILLA",
          "title": "Vanilla",
          "priceCents": 8850,
          "inStock": true,
          "inventoryQuantity": 12
        }
      ]
    }
  ]
}