Skip to main content
POST
Create or update up to 1,000 products in one call

Authorizations

X-API-Key
string
header
required

Body

application/json

Up to 1,000 normalised rows to merge into the catalog in this request.

source
enum<string>
required

Catalog source this batch merges under. One of: sephora_catalog, ulta_catalog. It decides the canonical retailer, its storefront and the per-field confidence table, exactly as it does for a catalog import job.

Available options:
ulta_catalog,
sephora_catalog
rows
CatalogRowIn · object[]
required

Rows to merge, at most 1,000 per call; a larger batch is refused with 422 before anything is written. The batch is one transaction — every row lands or none does. A barcode repeated inside the batch is merged once and the repeats are reported as duplicate; the server does not remember barcodes across calls, so a feed split over several calls should drop its own repeats between them.

Required array length: 1 - 1000 elements
source_file
string
default:""

Name of the feed drop these rows came from, recorded as listing provenance.

Maximum string length: 255
fetched_at
string<date-time> | null

When the feed drop was fetched. Send the drop's own timestamp; omitting it stamps the time of this request, which misdates a feed loaded weeks after it was published.

dry_run
boolean
default:true

Run the real merge and roll it back. Default. The outcomes and counts are the ones a committing call would return, so this is a rehearsal rather than an estimate. Send false to commit; committing is limited to Closient staff and the catalog-import service account, and anyone else gets 403.

reclaim_unattributed
boolean
default:true

Allow this batch to claim fields on imported products that carry no recorded provenance, as a catalog import job does by default. A brand-claimed product is never touched either way.

Response

OK

The batch's census and one outcome per row.

committed
boolean
required

True when the batch was written; false for a dry run.

result
Result · object
required

The same census a catalog import job reports: products created, enriched and unchanged, listings created and updated, duplicates, quarantine counts by reason, per-field decisions, and brand and ingredient figures. A dry run reports the labels it would parse as ingredients_would_parse.

rows
ProductBatchRowOut · object[]
required

One entry per input row, in request order.

ingredients_queued
integer
required

Ingredient labels handed to background parsing after the commit. Parsing runs at roughly 20 labels a second, so it is kept off the request; zero on a dry run.