Guides
Querying and pagination
Filter, sort, search and page through records, with cursor pagination for integrations that need to go deeper.
GET a list or POST a query
GET /{resource} and POST /{resource}/query use the same read path. GET encodes filters in the singular filter query parameter; POST uses a filters array in its JSON body. POST /query works with a read-only key. Unknown or repeated query parameters return 400 invalid_request.
| Parameter | Meaning |
|---|---|
page / cursor | Choose one pagination mode. Page defaults to 1; start a cursor walk with start. |
page_size | 1–100 records; default 25. |
sort / order | A sortable field key, and asc or desc. Default order is newest first. |
search | Free-text search on resources with searchable: true; ranks a bounded 500-candidate window. |
include_archived | Include archived records; false by default. |
filter / filters, join | Structured filters, combined with and (default) or or. |
fields | Comma-separated names in GET; an array in POST /query. |
model_id | Required for data_model_records; does not apply to other resources. |
Use certified filters
Each filter has field, op and, when needed, value. Fields, operators and values are checked against the workspace’s capabilities. A native field uses its field key; custom fields use the described filter_key; related fields use rel:<foreign-key-column>.<column>.
| Operators | Value |
|---|---|
eq, ne, gt, gte, lt, lte | A compatible scalar. |
iLike, notILike | Case-insensitive text matching. |
inArray, notInArray | An array of compatible values. |
isBetween | A two-value range. |
isEmpty, isNotEmpty | No value needed. |
curl --fail-with-body --request POST "$SQUARIO_API_BASE/companies/query" \
--header "Authorization: Bearer $SQUARIO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"filters": [{ "field": "name", "op": "iLike", "value": "Northfold" }],
"join": "and",
"page_size": 25,
"fields": ["name"]
}'curl --fail-with-body --get "$SQUARIO_API_BASE/companies" \
--header "Authorization: Bearer $SQUARIO_API_KEY" \
--data-urlencode 'filter=[{"field":"name","op":"iLike","value":"Northfold"}]' \
--data-urlencode 'fields=name' \
--data-urlencode 'page_size=25'Read the pagination metadata
A list returns data and meta. Page mode includes page, page_size, total and has_more. total_is_capped: true means total is a lower bound. Page numbers address an offset window through 10,000; requests past the permitted page return 400 with details.max_page. For exports and deep synchronisation, use cursors.
{
"data": [{ "id": "c91b7028-f985-4bc1-9f75-c76533c3133a", "name": "Northfold" }],
"meta": { "page": 1, "page_size": 25, "total": 1, "has_more": false }
}Walk with an opaque cursor
Send cursor=start, then send the response’s meta.next_cursor unchanged until it is null. Do not also send page. Keep filters, sort and other query settings stable throughout the walk. A cursor is a position, not a snapshot of a changing workspace.
- Cursor responses carry
page_size,next_cursor,cursor_supported,totalandhas_more. - Free-text relevance sorting cannot be walked;
cursor_supportedis false on its first page. Use page mode for that query. - A positioned cursor that does not match the query returns 400. Restart the walk after changing the sort or filters.
- Treat cursors as opaque. Do not decode, edit or manufacture them.
const base = process.env.SQUARIO_API_BASE?.replace(/\/$/, "");
const key = process.env.SQUARIO_API_KEY;
if (!base || !key) throw new Error("Set SQUARIO_API_BASE and SQUARIO_API_KEY");
let cursor = "start";
while (cursor !== null) {
const url = new URL(`${base}/companies`);
url.searchParams.set("cursor", cursor);
url.searchParams.set("page_size", "100");
url.searchParams.set("fields", "name");
const response = await fetch(url, {
headers: { Authorization: `Bearer ${key}` },
signal: AbortSignal.timeout(30_000),
});
const body = await response.json();
if (!response.ok) throw new Error(`${body.error.code} (${body.error.request_id})`);
if (!body.meta.cursor_supported) throw new Error("Use page mode for this sort");
for (const record of body.data) console.log(record.id, record.name);
cursor = body.meta.next_cursor;
}