Start a run
A batch of product identities in, a run id back. 202, not 200: the work has been accepted, not done — poll GET /runs/{id}. Needs catalog:write and an Idempotency-Key header: a retried POST with the same key does not scrape the batch twice.
Send NDJSON (one object per line, application/x-ndjson) or a JSON array. Lines are accepted or rejected individually: a batch of 5,000 with one bad row scrapes 4,999 and tells you which line failed. Every line needs a vendor SKU (sku or vendorSku) — it is what the supplier's site is indexed by, and a line without one is rejected.
Each line needs something to scrape against: either a categoryId whose category has a golden mapping, or its own attributes. A line with neither is refused as no_gold_match rather than scraped for generic attributes.
Authorization
apiKey Your API key. X-Api-Key: <key> is accepted as an alternative.
A key belongs to an organization, not a user, so it outlives whoever created it. It carries two independent things, and both are checked: an org role (a member key cannot approve a publish or activate a mapping) and a set of scopes — catalog:read, catalog:write, enrichment:write, publishing:read, publishing:write, org:read, org:write. Holding a scope does not grant a role, and holding a role does not grant a scope.
GET /v1/me returns both for the key you are holding.
In: header
Path Parameters
Which of your brands this run belongs to. A brand outside your organization answers not found.
TypeScript Definitions
Use the request body type in TypeScript.
One of these per line.
Response Body
application/json
application/json
application/problem+json
application/json
application/json
application/json
application/problem+json
curl -X POST "https://example.com/v1/brands/string/catalog-builder/runs" \ -H "Content-Type: application/json" \ -d '[ { "ref": "string", "title": "string" } ]'{ "accepted": -9007199254740991, "refused": -9007199254740991, "rejected": [ { "line": -9007199254740991, "reason": "string", "ref": "string" } ], "runId": "string"}Move an attribute between product and variant scope PATCH
Scope says where an attribute's values live on a product that has variants; on a product without variants the attribute is the product's own either way. Moving to `variant` copies each product's value onto its variants that hold none (a variant's own value is never overwritten), then removes the product's value; a product without variants keeps its value as its own. Content Fabric writes per product cannot move to `variant`. Moving to `product` takes the value a product's variants agree on onto the product and removes it from the variants. Agreement is strict: every variant holds the same value, or none does. If any product disagrees, nothing moves and the answer is 409 with one `errors` entry per product (at most 20). Every value written is recorded in its history against the API key, and the change appears in the brand's activity. A move rewrites up to 25,000 variants in one transaction, so it sits on the `job` budget.
Poll a run GET
Status, counts and progress. `processed` reaches `total` even when a third of the catalog is unfindable — every identity finishes, with a result or a failure.