Lists & filtering
Every endpoint that lists a resource wraps the result in an items array, whatever the resource.
The list envelope
List endpoints return a JSON object with a single items array — never a bare array at the top level:
{
"items": [
{
"id": "6f1c2b7a-9d3e-4a51-8b0c-2e7f4d9a1c33",
"name": "api-demo",
"status": "running",
"planId": "nano",
"regionId": "nl-ams",
"ipAddress": "203.0.113.42"
}
]
}So GET /api/v1/instances, GET /api/v1/volumes, GET /api/v1/reserved-ips, GET /api/v1/api-keys, and the other collection routes all give you { "items": [ ... ] }. Read the array at items; an empty collection is { "items": [] }, not null.
Always the same shape
A resource list is always an object with an items array — even when it's empty and even on the paginated endpoints below. Read the list from items on every resource-list route. A few composite endpoints (/wallet/summary, /instances/{id}/metrics/history) nest their array under a different key, documented per endpoint.
Pagination
Most collections are not paginated. Routes like /instances, /volumes, /reserved-ips, /vpcs, and /api-keys return the full set you own in one response — there is no limit, offset, page, or cursor parameter, and no total count. These lists are scoped to your account and stay small, so fetch once and work with the whole array.
A few high-cardinality endpoints — the ones that can grow without bound — are paginated with offset / limit. There are no cursors anywhere in the API. Paginated responses add total, limit, and offset alongside items:
{
"items": [ /* ... */ ],
"total": 214,
"limit": 25,
"offset": 0
}limit— page size,1–100, default25.offset— how many rows to skip,0or greater, default0.total— the full count matching your filters, so you can compute how many pages remain.
Step through pages by advancing offset in multiples of limit (0, 25, 50, …) until offset + items.length reaches total. Some of these endpoints also include an extra stats object with server-computed aggregates — always trust stats and total over anything you'd derive from a single page.
The paginated collections are:
| Endpoint | Paginated | Extra stats |
|---|---|---|
GET /wallet/transactions | ✓ | — |
GET /tickets | ✓ | — |
GET /backups | ✓ | ✓ |
GET /backups/servers | ✓ | — |
GET /monitoring/servers | ✓ | ✓ |
Filtering
Only the paginated endpoints take query parameters — the plain { "items": [] } collections accept none, so filter those client-side. Every filter is optional, and a free-text q (matched server-side) is available on each. The real parameters:
| Endpoint | Filters (besides limit / offset) |
|---|---|
GET /wallet/transactions | q, type (credit, debit), category (topup, usage, refund, adjustment), month (YYYY-MM) |
GET /tickets | q, status (open, answered, closed) |
GET /backups | q, type (auto, manual) |
GET /backups/servers | q |
GET /monitoring/servers | q, status (provisioning, running, stopped, error, destroyed) |
Combine filters with paging in the query string:
# Second page of this month's usage charges, 50 per page
curl -G https://console.ekire.net/api/v1/wallet/transactions \
-H "Authorization: Bearer $EKIRE_API_KEY" \
--data-urlencode "category=usage" \
--data-urlencode "month=2026-07" \
--data-urlencode "limit=50" \
--data-urlencode "offset=50"Passing a value outside the allowed range (for example limit=500) or an unrecognized enum value returns 400 Bad Request rather than being silently clamped.