Requests & responses
Base URL
https://api.stylumia.com
TLS only — there is no unencrypted variant to fall back to. Every request and response body is JSON.
The envelope
Every /v1 success response is shaped the same way, regardless of endpoint:
{
"data": [ "..." ],
"pagination": { "limit": 100, "total_matching": 2361, "next_cursor": "...", "has_more": true },
"meta": {
"request_id": "req_...",
"resolved": { "retailer": null, "category": "power_tools", "department": null, "rcd": null, "start_date": null, "end_date": null },
"coverage": { "combinations": 1, "matching_rows": 6, "corpus_rows": 2361, "earliest_date": "2026-06-14", "latest_date": "2026-08-14" }
}
}
| Member | Meaning |
|---|---|
data |
The rows you asked for — an array on every endpoint here. |
pagination.limit, pagination.total_matching |
Only present on /v1/catalog — the page size and the size of the whole filtered set. |
pagination.next_cursor |
Opaque cursor for the next page, or null if there isn't one. |
pagination.has_more |
Whether another page exists. |
meta.request_id |
This request's id — also echoed in the X-Request-Id header. |
meta.resolved |
The six filters the server actually used — retailer, category, department, rcd, start_date, end_date — including ones you didn't send. |
meta.coverage |
How much exists for those filters — rides on every response, not just /v1/coverage. See Coverage. |
meta.resolved
If you call /v1/catalog?retailer=home_depot and omit every other filter,
meta.resolved tells you exactly what the server used:
{"retailer": "home_depot", "category": null, "department": null, "rcd": null, "start_date": null, "end_date": null}. You never have to guess which
filters actually applied. limit isn't part of meta.resolved — it lives
in pagination.limit on /v1/catalog, where a silently-applied default of
100 can otherwise cost you a page of data you didn't mean to skip. See
Pagination.
meta.coverage
Every response — /v1/sample, /v1/catalog, and /v1/coverage alike —
carries a coverage block: how many RCD combinations your filters matched,
how many rows matched across them, how many rows those combinations hold in
total, and the date range spanned. One request answers both "what did I
get" and "how much exists" — you don't need a second call to /v1/coverage
just to see the total. See Coverage & RCD combinations.
request_id
Every response — success or problem+json error —
carries a request_id, both in the body and in the X-Request-Id response
header. It's derived server-side from a SHA-256 digest of the caller, the
request, and the timestamp — you never supply one, and there's no
request-id header to send. Quote the value you're given when you write to
Support; it's the fastest way for us to find your exact
request server-side.
request_id is safe to log and safe to paste into a support ticket. It
identifies a request, not a secret.
What's safe to log
| Safe to log | Not safe to log |
|---|---|
request_id |
The full API key |
| The key's name, from the console | The key itself, in any form |
| Endpoint path and query parameters | — |
Naming your keys is precisely what lets you log and grep for "which key made this call" without the log itself becoming a credential. See Credential security for the rest of the credential-handling rules.