Skip to main content
GET

Authorizations

Authorization
string
header
required

Workspace-scoped API key (mk_live_...). Each operation lists the scope it requires in x-required-scopes. See the Authentication guide for the full scope table and key management.

Query Parameters

limit
integer
default:50

Rows per page, 1 to 200. Defaults to 50.

Larger pages mean fewer round-trips. 200 is also the cap on in operator value lists, so refetching a full page of IDs with filter[id][in]=... always fits in one call.

Required range: 1 <= x <= 200
offset
integer
default:0

Rows to skip. Zero-based. Echoed back in pagination.offset.

Page forward by adding limit each time. Stop when pagination.has_more is false rather than comparing counts. Default order is created_at ascending, which keeps long sweeps stable: new rows land at the end instead of shifting pages you have not read yet.

Required range: x >= 0
sort
string

Comma-separated keys. Prefix with - for descending: sort=-updated_at,sku. Defaults to created_at ascending.

Sortable: text, number, and date attributes, plus id, parent_id, created_at, and updated_at. Reference and list-reference keys have no scalar order. Sorting on one returns 400 (not_sortable).

filter
object

Narrow results by attribute value. Filtering runs in the database, so pagination.total reflects matches, not the whole catalog.

Two forms: filter[sku]=ARIA-DT-72 is shorthand for equals. filter[price][gte]=100 uses the bracket-operator form filter[<key>][<op>]=<value>.

Keys: any attribute key from GET /attributes, plus id, parent_id, created_at, and updated_at. Reference keys like vendor match on UUID, not name.

Operators:

  • Text: eq, ne, contains, not_contains, starts_with, ends_with
  • Number, date, timestamp: gt, gte, lt, lte. A bare date means UTC midnight.
  • Any type: exists (=true has a value, =false is blank)
  • Text, id, and reference keys: in (comma-separated OR-of-equals, up to 200 values)

Examples:

  • filter[sku]=ARIA-DT-72 one product by your own identifier
  • filter[description][exists]=false everything missing a description
  • filter[price][gte]=100&filter[material]=Oak both must match (see filter_join)
  • filter[id][in]=<uuid1>,<uuid2> refetch a known set in one call
  • filter[vendor]=<uuid>&sort=-updated_at one vendor's catalog, newest first

A bad filter never silently matches everything. Unknown keys, unknown operators, or type mismatches return 400 with field_errors naming the exact clause.

Brackets and spaces need URL-encoding. With curl, use -G --data-urlencode "filter[vendor_name]=Nordic Timber Co.". In JavaScript, let URLSearchParams handle it.

filter_join
enum<string>
default:and

How multiple filter clauses combine. and means every clause must match (the default). or means any clause can match. Case-insensitive. Any other value returns 400.

Only matters with two or more clauses. One join applies to all of them. There is no grouping or nesting, so mixed AND/OR logic belongs on your side.

For OR across values of the same key, prefer filter[<key>][in]=a,b,c. One clause, up to 200 values, and it reads better in a log.

Available options:
and,
or
fields
string

Return only the attribute keys you name instead of every populated one. Useful when a workspace has hundreds of attributes and your integration reads a handful.

fields=sku,price (comma-separated) or fields=sku&fields=price (repeated param, same result). Omit it entirely to get every populated key.

Only the attributes map narrows. System fields (id, type, label, parent_id, created_at, updated_at) always come back, so naming one returns 400. label still resolves from the primary attribute whether or not you select it. pagination.total is unchanged. filter and sort are independent: filter on keys you did not select.

Sparse still means sparse. A selected key with no value stays absent. Keep reading attributes[key] ?? null.

Reference keys return {id, type, label} stubs as usual, but fields does not reach through them. fields=gallery_images.image_url is not supported. Select the reference key, then batch-fetch: GET /images?filter[id][in]=<ids>&fields=image_url.

Unknown keys return 400 with field_errors. Inverse-reference keys are rejected the same way. They are queries, not stored values. Read them via /{resource}/{id}/references?attribute=.

Selecting only non-reference keys skips the reference join entirely, which avoids loading every referenced entity just to attach its label.

Response

A page of sources.

data
object[]
pagination
object
Example: