Skip to main content
COMMERCE DATA INFRASTRUCTURE/PREVIEW · TIKTOK SHOP LIVE

Ask once. Every source runs until one answers.

Unif cascades every request across its commerce data sources in cost order and stops at the first verified hit — normalized into one schema, whichever source answered. You pay only when something comes back.

Misses are free · 47 endpoints · 6 entities · first row in five minutes

POST /v1/products/search

The waterfall

One request. Every source, in cost order. One charge.

The cascade is already built and tuned. You do not pick sources, order them, or write the fallback logic — and the sources you never reach cost you nothing.
REQUEST · revenue for shp_01k3…d7fa · last 30 days · USDCREDITS
01no record for this shopno match0
02{ “sales_amount”: “1,284,300.25” }unverified0
03{ “gmv”: 1284300.25, “cur”: “USD” }verified ✓1
04not reached
05not reached
RETURNED  { “metrics”: { “revenue”: 1284300.25 }, “currency”: “USD”, “period”: { “adjusted”: false } }

Whichever source answers

The record is identical no matter which step of the cascade produced it. No aliases, no branching on source.

One currency, daily rates

Converted per day of the period, so a historical number stays the same number next week.

Absent is null, never zero

A field a channel does not report comes back null and named. Nothing is quietly modelled.

SOURCES IN THE CASCADE
Kalodata[ SOURCE 02 ][ SOURCE 03 ][ … ]
Published. Which one answered a given row is not.

The model

Six entities. The same six on every channel.

Stable IDs that survive renames, handle changes and re-listings. Store the ID, not the URL.
ENTITYIDWHAT IT ISSIGNALS YOU FILTER AND SORT ON
Shopshp_A storefront or sellerrevenue · revenue_by_source · creators_count
Productprd_One listing, in one marketrevenue · avg_sale_price · commission_rate
Creatorcrt_An affiliate who drives salesgpm · engagement_rate · followers
Videovid_Shoppable short-form contentviews · gpm · revenue
Livestreamliv_One live selling sessionviewers · avg_watch_seconds · revenue
Categorycat_A node in the shared treerevenue_growth_rate · shops_count
Category IDs are shared across channels — not per-channel. A filter written against cat_beauty_personal_care today keeps selecting beauty when you turn the next channel on.

What you do with it

Search the market. Enrich your rows. Get told when it moves.

01Search
Start from filters, not identifiers. Range filters, multi-key sorting and cursor pagination across all six entities.
POST /v1/products/search
02Enrich
Start from rows you already have. Send the URLs and handles you hold; get back stable IDs and the fields you asked for, 100 at a time.
POST /v1/enrich
03Track
Stop polling. Put a set behind a tracker and get a signed webhook when a metric actually crosses your threshold.
POST /v1/trackers

What comes back

The same request, rendered for someone who does not read JSON.

Six rows from the search in the hero. Every column is a field in the schema, and the trend comes from the same entity’s timeseries endpoint.
PRODUCTPRICEREVENUE 30DGROWTHTRENDCREATORSCOMMISSION
Ceramide Barrier Repair Serum 30ml
GlowLab
28.00</td><tdclassName="unumunumlead">28.00</td> <td className="u-num u-num--lead">184,320+81%21420%
Overnight Peptide Lip Mask
Aura Beauty
19.50</td><tdclassName="unumunumlead">19.50</td> <td className="u-num u-num--lead">142,880+34%16818%
Volumizing Dry Shampoo 200ml
NorthPeak
24.00</td><tdclassName="unumunumlead">24.00</td> <td className="u-num u-num--lead">118,540−12%9615%
Niacinamide Pore Refining Toner
GlowLab
22.00</td><tdclassName="unumunumlead">22.00</td> <td className="u-num u-num--lead">97,210+52%14122%
Scalp Detox Rosemary Oil
Verdant Co
31.00</td><tdclassName="unumunumlead">31.00</td> <td className="u-num u-num--lead">88,470+19%7325%
Hydrocolloid Blemish Patch ×72
Aura Beauty
15.00</td><tdclassName="unumunumlead">15.00</td> <td className="u-num u-num--lead">76,330+7%20517%
Sample values, for layout6 of 418 matches · 6 credits

Coverage

Know what a field is worth before you build on it.

One endpoint grades every field for the market you are working in: how complete it is, whether you can filter on it, and how far behind it runs.
So a thin field turns up while you are writing the query — not three weeks later, in a dashboard nobody can explain.
How coverage works
GET /v1/coverage?entity=creator&market=ID
metrics.revenue
Filterable · sortable · typically 24h behind
FULL
metrics.engagement_rate
Not filterable · populated above 10k followers
PARTIAL
agency
Not disclosed by the channel in this market
UNAVAILABLE
CHANNELS
LIVETikTok Shop16 markets · all six entities · daily refresh
Amazon, Shopee & Lazada and Shopify are on the roadmap — same filters, same stored IDs, no migration on your side.

Your first enriched row is one request away.

The quickstart takes you from an API key to a normalized record. Nothing to install.