External product API

Bootstrap and synchronize an externally owned catalog with verified request examples.

Authentication and base URL

Use your environment's API origin with /api/v1. These external routes use integration authentication, not a dashboard JWT. Configure an active PRODUCT_SYNC or CUSTOM_API integration for the business and use its selected authentication method. In API-key mode send x-api-key; in HMAC mode follow request signing.

MethodRelative path under /api/v1Operation
POST/businesses/:businessId/integrations/products/bootstrapInitial import/upsert
POST/businesses/:businessId/integrations/products/syncOngoing update

Bootstrap request

Product external_id and name, a nonempty variants array, and variant SKU are required. Variant price is a number. Use explicit currency and stable variant external IDs.

{
  "products": [{
    "external_id": "catalog-100",
    "name": "Reusable bottle",
    "nameAr": "زجاجة قابلة لإعادة الاستخدام",
    "isAIVisible": true,
    "variants": [{
      "external_id": "catalog-100-blue",
      "sku": "BOTTLE-BLUE",
      "price": 49,
      "currency": "SAR",
      "availability": true,
      "stock_quantity": 12
    }]
  }]
}

Bootstrap upserts by the business's product external ID. Variant external_id defaults to SKU when omitted; supply it explicitly when your source has a stable identifier. The response contains success, imported, updated, and failed. Each failed item contains external_id and reason. Inspect failed even when the HTTP request succeeds; bootstrap processes records individually.

Update a variant

{
  "event": "variant.updated",
  "variant": {
    "external_id": "catalog-100-blue",
    "price": 45,
    "currency": "SAR",
    "availability": true,
    "stock_quantity": 8
  }
}

Use product.updated with product.external_id for product fields. The service also handles product.deleted (marks inactive), variant.deleted, and product.hard_deleted. Deletion events are destructive; use a disposable test record and confirm the exact event semantics before enabling source deletion. Sync responses contain success, event, message, and updatedAt where returned.

Failure handling

Missing identifiers or unsupported events are rejected. Unknown external records return not-found errors. Check partial bootstrap failures and the current provider record before replaying. There is no pagination on these POST operations; do not invent a list endpoint from their names. Source verification does not replace a controlled test against the deployed backend.