Skip to main content
Every entity has a Unif ID: a prefix, then a sortable 26-character identifier.
The prefix means an ID is self-describing in a log line, and passing a crt_ ID to a shop endpoint fails immediately with parameter_invalid rather than returning a confusing 404.

Why not just store the URL

URLs are not identity. Over a few months a storefront can change its handle, a product can be delisted and re-listed under a new native ID, and a channel can migrate its URL structure — all without the underlying entity changing.

A Unif ID survives

Renames, handle changes, re-listings and URL migrations. It is assigned once and never recycled.

A URL does not

It is a lookup key that happens to work today. Storing it means re-resolving forever, and paying for it every time.
Resolve once, store the ID on your row, and every later call is a direct lookup.

Resolving what you already have

POST /v1/resolve accepts up to 100 inputs and takes any of three identifier forms.
  • url — the most reliable form. Channel and market are inferred from it.
  • handle — needs market, because the same handle can exist in several markets.
  • external_id — the channel’s native ID. Needs channel to be unambiguous.
ref is yours. Unif echoes it back untouched, which turns joining results onto your own rows into a dictionary lookup instead of positional bookkeeping.

Four possible outcomes

Results come back in the order you sent them, and one input failing never fails the batch.
Exactly one match. id is set and safe to store.
No match. Usually a dead listing, a typo, or an entity in a market your workspace has not enabled. Retrying will not help; the input needs fixing.
More than one match — most often the same product under multiple shops. candidates lists them so you can disambiguate with a rule of your own, or surface the choice to a person.
The channel or entity type is not enabled for your workspace. Check GET /channels; this is an entitlement problem, not a data problem.

Resolve, or enrich

POST /v1/enrich takes exactly the same input shape and returns the full record instead of just the ID. Enriching costs more than resolving, so for a one-time backfill of 50,000 rows, resolve first and then pull metrics only for the rows you keep.

Idempotent by design

Resolving the same identifier twice returns the same ID. There is no create-or-get race, and no deduplication step needed on your side. The one thing to handle is ambiguous — the same input stays ambiguous until you pick a candidate, so record the decision on your row rather than re-resolving and hoping.