Get startedPagination & errors
Pagination & errors
List endpoints return results in pages using opaque cursors, and every failure follows one predictable error shape. Handle both once and you're covered across the whole API.
Cursor pagination
List responses wrap rows in a data array alongside a pagination object. To fetch the next page, pass the nextCursor value back as the cursor query parameter. Keep going until nextCursor comes back null — that is the last page.
| Parameter | Type | Description |
|---|---|---|
| limit | integer | Rows per page. Default 50, maximum 200. |
| cursor | string | Opaque cursor from a previous response's nextCursor. |
The pagination object on every list response:
pagination
"pagination": {
"nextCursor": "eyJpZCI6MTQ4Mn0",
"limit": 50
}Paging through every result
async function listAll(params = {}) {
const out = [];
let cursor = null;
do {
const qs = new URLSearchParams({ ...params, limit: "200", ...(cursor ? { cursor } : {}) });
const res = await fetch(`https://api.gpus.io/v1/prices?${qs}`, {
headers: { Authorization: `Bearer ${process.env.GPUS_API_KEY}` },
});
const page = await res.json();
out.push(...page.data);
cursor = page.pagination.nextCursor;
} while (cursor);
return out;
}Errors
GPUs.io uses conventional HTTP status codes and returns a single, consistent error envelope. The code is a stable, machine-readable string you can branch on; some errors add an optional details object.
400 Bad Request
{
"error": {
"code": "INVALID_PARAMETER",
"message": "Invalid minVram: must be a non-negative number"
}
}Status codes
| Status | Code | Meaning |
|---|---|---|
| 200 | — | Success. |
| 400 | INVALID_PARAMETER | A parameter is missing, malformed, or out of range. |
| 401 | UNAUTHORIZED | Missing, malformed, or unknown API key. |
| 404 | NOT_FOUND | The requested resource (e.g. a GPU key) doesn't exist. |
| 429 | RATE_LIMITED | You exceeded a rate limit — see Rate limits. |
| 500 | INTERNAL | Something went wrong on our end. Safe to retry. |
Handling errors
const res = await fetch(url, { headers });
if (!res.ok) {
const { error } = await res.json();
if (res.status === 429) {
const retry = Number(res.headers.get("Retry-After") || 1);
await new Promise(r => setTimeout(r, retry * 1000));
// ...then retry
}
throw new Error(`${error.code}: ${error.message}`);
}