Skip to main content

Pagination & Response Envelope

All endpoints in the API follow a consistent response envelope. List endpoints support offset-based pagination.

Response Envelope

Every response — success or error — is wrapped in a standard envelope. This makes it safe to always check success first before accessing data.

List endpoints

{
"success": true,
"data": [ ... ],
"meta": {
"total": 150,
"limit": 25,
"offset": 0
}
}
FieldTypeDescription
successbooleantrue when the request completed without errors
dataarrayThe matching resources for this page
meta.totalintegerTotal records matching the query after filters, before pagination
meta.limitintegerNumber of records returned in this page
meta.offsetintegerNumber of records skipped (starting position)

Single-resource endpoints

GET-by-ID endpoints return data as an object, not an array. The meta field may be empty or omitted:

{
"success": true,
"data": {
"id": "104820579301",
"name": "Truck-42",
"plate": "ABC-1234",
"status": "A"
},
"meta": {}
}

Write operations (POST / PUT)

Create and update endpoints return the created or updated resource in data:

{
"success": true,
"data": {
"id": "104820579305",
"name": "Truck-New",
"plate": "XYZ-9999",
"status": "A",
"createdAt": "2026-04-04T14:30:00"
},
"meta": {}
}

Error responses

When an error occurs, data is always null and the error object contains the details. See Error Handling for the full reference.

{
"success": false,
"data": null,
"error": {
"code": "VALIDATION_ERROR",
"message": "\"limit\" must be a number between 1 and 100"
}
}

Pagination

List endpoints support limit/offset pagination through query parameters:

ParameterTypeDefaultMaxDescription
limitinteger25100Number of records per page
offsetinteger0Number of records to skip

Examples

First page (default):

GET /apidev/v1/fleet/devices?limit=25&offset=0
→ records 1–25

Second page:

GET /apidev/v1/fleet/devices?limit=25&offset=25
→ records 26–50

Third page:

GET /apidev/v1/fleet/devices?limit=25&offset=50
→ records 51–75

Calculating total pages

const totalPages = Math.ceil(meta.total / meta.limit);
// total: 150, limit: 25 → 6 pages

Iterating through all pages

async function fetchAllPages(baseUrl, headers) {
const limit = 100;
let offset = 0;
let allRecords = [];

while (true) {
const response = await fetch(
`${baseUrl}?limit=${limit}&offset=${offset}`,
{ headers }
);
const json = await response.json();

allRecords = allRecords.concat(json.data);

if (offset + limit >= json.meta.total) break;
offset += limit;
}

return allRecords;
}

// Usage
const devices = await fetchAllPages(
`https://${TENANT}/apidev/v1/fleet/devices`,
headers
);
tip

Set limit=100 (the maximum) when iterating through all pages to minimize the number of API calls and stay within rate limits.


Filters and Pagination

Filters are applied before pagination. The meta.total value reflects the count of records that match your filters, not the total in the database.

GET /apidev/v1/fleet/devices?status=A&limit=25&offset=0
{
"success": true,
"data": [ ... ],
"meta": {
"total": 42,
"limit": 25,
"offset": 0
}
}

In this example, 42 devices have status=A — not 42 total devices in the system. Page calculations should use this filtered total.


Sort Order

List endpoints return results in a deterministic order, typically by primary key or creation date descending (newest first). Individual endpoint documentation specifies the default sort when it differs from this convention.

The API does not expose a generic sort query parameter — the sort order is fixed per endpoint to ensure consistent pagination across pages.


Empty Results

When a query matches no records, the response uses the standard envelope with an empty array:

{
"success": true,
"data": [],
"meta": {
"total": 0,
"limit": 25,
"offset": 0
}
}

This is not an error — success is true. Your code should handle empty data arrays gracefully rather than treating them as failures.

warning

The maximum allowed value for limit is 100. Requesting a higher value returns a VALIDATION_ERROR.