Talk to your AI agent to run Simetrik. →
SimetrikDocs

Reference

The endpoint, every parameter, the response shape and each error it can return.

Endpoint

GET /api/v1/resources/{resource_id}/data
Path parameterTypeDescription
resource_idintegerThe resource to read. A non-numeric value is 422.

Headers

HeaderRequiredDescription
X-API-KeyYesYour API key.
workspace_idYesNumeric id of the workspace that owns the resource.

Query parameters

ParameterTypeDefaultDescription
pageinteger1One-based page number.
page_sizeinteger1000Rows per page. Minimum 1, maximum 10000 — higher values are capped silently.
fieldsstring(all columns)Comma-separated column names to return.
orderingstring(unordered)One column name. Prefix with - for descending.
anything elsestring—A filter. See below.

Filters

Any parameter that isn't one of the four reserved names is read as a filter on the column of that name.

FormOperatorExample
column=valueEqual tostatus=RECONCILED
column__exact=valueEqual tostatus__exact=RECONCILED
column__gt=valueGreater thanA.amount__gt=1000
column__gte=valueGreater than or equalA.date__gte=2026-09-01
column__lt=valueLess thanA.amount__lt=5000
column__lte=valueLess than or equalA.date__lte=2026-09-30
column__in=a,b,cAny ofA.country__in=Colombia,Mexico

Multiple filters are combined with AND. Column names are the labels shown in Simetrik and are case-sensitive. Any other operator suffix is 400.

Paging

page is one-based, and paging is offset-based: page=3 skips the first 2 × page_size rows. Read pages until returned_count is lower than meta.page_size — that's the end of the result set, and it's a more robust test than comparing against total_pages.

Always send ordering when you read more than one page. Without an explicit sort, the order rows come back in isn't guaranteed to be the same between requests, so a row can be skipped or returned twice as you walk the pages. Sort by a column with unique values — an id is ideal. If rows are being written while you read, also filter to a closed window (a date range that's already over) so new rows stay out of the result set. That doesn't freeze it — a row that arrives late with a date inside the window can still shift the pages — so when completeness matters, de-duplicate on the unique column you sort by and treat total_count as a sanity check, not proof: a repeated row and a missed one can cancel out. If the counts disagree, re-read the window.

Caching

Identical requests are served from a cache for five minutes. Identical means the same workspace, resource, page, page size, fields, ordering and filters — change any one of them and it's a different entry.

So data can be up to five minutes stale, and polling faster than that returns the same response, including the same total_count. Cache entries are scoped per workspace and ownership is checked before the cache is read, so a cached response never crosses workspaces.

Response

200 OK:

{
  "data": [
    {"A.id": "TX-0001", "A.amount": 1500, "status": "RECONCILED"}
  ],
  "meta": {
    "page": 1,
    "page_size": 1000,
    "returned_count": 1,
    "total_count": 1,
    "total_pages": 1
  }
}
FieldTypeDescription
dataarrayThe rows. Each object is keyed by column name. Empty when nothing matched.
meta.pageintegerPage returned.
meta.page_sizeintegerPage size actually applied, after capping.
meta.returned_countintegerRows in this response.
meta.total_countintegerRows matching the filters across the resource.
meta.total_pagesintegertotal_count ÷ page_size, rounded up.

Responses larger than about 1 KB are gzip-compressed.

Errors

StatusdetailCause
400workspace_id must be a valid integerThe header isn't numeric.
400Filter field '<name>' is not a valid column for this resource.Unknown column in a filter — often a misspelled reserved parameter.
400Field '<name>' is not a valid column for this resource.Unknown column in fields.
400Ordering field '<name>' is not a valid column for this resource.Unknown column in ordering.
400Operator '<op>' is not supported.Unknown __suffix.
400The requested filters or ordering could not be applied.The query was rejected downstream — usually a value whose type doesn't match the column.
401Could not validate credentialsMissing or invalid X-API-Key.
403Resource does not belong to the specified workspaceOwnership mismatch.
404Workspace not foundNo workspace with that id.
404Resource not foundNo resource with that id.
422Validation error objectMissing workspace_id header, page_size below 1, or a non-numeric resource_id. Headers and declared parameters are validated first, so a workspace_id sent in the query string fails here as a missing header rather than being read as a filter.
503Data platform is temporarily unavailable. Please try again later.Transient. Retry with backoff, and with a smaller page_size if it repeats.

Errors carry a detail field. 422 follows the standard validation-error shape, with detail as an array identifying the offending parameter.

Health

GET /health

Returns {"status": "ok"}. No authentication, and no check of the data platform behind it.

OpenAPI

The service publishes its own OpenAPI document at /api/v1/openapi.json, which is handy for generating a client.

On this page