Skip to main content

Listing and Pagination

Every GET endpoint that returns a collection (/v1/portal_users, /v1/dashboard_users, /v1/team_roles, etc.) uses page-number pagination.

Parameters​

Sent in the query string:

ParameterTypeDefaultDescription
pageinteger ≥ 11Requested page (starts at 1).
per_pageinteger 1–10020Items per page. Maximum 100.
sort_bystringvaries by resourceField used for sorting. Accepts the same names as the response.
sort_orderasc or descdescSort direction.

Out-of-range values are clamped (e.g. per_page=999 becomes 100; page=0 becomes 1).

Response​

Every listing follows this envelope:

{
"data": [
{ "id": "8b2f4c1e-6a3d-4f0b-9c7e-2d5a1b3c4d5e", "email": "joao@example.com", "status": "active", "tenant_id": "cliente-1042" }
],
"meta": {
"total": 142,
"page": 1,
"per_page": 20,
"total_pages": 8
}
}
FieldDescription
dataArray with the items of the current page.
meta.totalTotal items matching the filters (not just the ones returned).
meta.pageCurrent page.
meta.per_pageItems per page actually applied.
meta.total_pagesTotal number of pages (ceil(total / per_page)).

The last page may contain fewer than per_page items. When page > total_pages, data is empty (not an error).

Examples​

First page, default​

curl -H "Authorization: Bearer $KOBANA_TOKEN" \
'https://api.dashboards.sandbox.kobana.com.br/v1/portal_users'

Page 3 with 50 items​

curl -H "Authorization: Bearer $KOBANA_TOKEN" \
'https://api.dashboards.sandbox.kobana.com.br/v1/portal_users?page=3&per_page=50'

Sorted by created_at ascending​

curl -H "Authorization: Bearer $KOBANA_TOKEN" \
'https://api.dashboards.sandbox.kobana.com.br/v1/portal_users?sort_by=created_at&sort_order=asc'

Filters + pagination​

Resource-specific filters work together with page/per_page:

curl -H "Authorization: Bearer $KOBANA_TOKEN" \
'https://api.dashboards.sandbox.kobana.com.br/v1/portal_users?status=active&email=joao&page=2&per_page=25'

Iterating over all pages​

Recommended pattern in pseudo-code:

async function fetchAll(url, token) {
const out = [];
let page = 1;
while (true) {
const res = await fetch(`${url}?page=${page}&per_page=100`, {
headers: { Authorization: `Bearer ${token}` },
});
const { data, meta } = await res.json();
out.push(...data);
if (page >= meta.total_pages) break;
page += 1;
}
return out;
}

Best practices​

  • For incremental sync, prefer filtering by updated_at_gte (or a similar filter available on the endpoint) instead of scanning every page.
  • per_page=100 minimizes the number of requests and uses less of the rate limit.
  • Cache meta.total when rendering paginators; don't recompute it on every navigation.
  • Don't assume a stable order without an explicit sort_by — the default order may differ between resources.