Docs menu
Errors, limits & pagination
How the API reports problems, how much you can call it, and how to page through results.
Error format #
Errors use standard HTTP status codes and a JSON body. Validation errors also list the fields that failed.
HTTP/1.1 400 Bad Request
{
"error": "Invalid request",
"issues": [{ "path": "datasetId", "message": "Required" }]
}| Status | Meaning | What to do |
|---|---|---|
| 400 | Invalid input, or the connected system rejected the request | Fix the request. Don't retry unchanged |
| 401 | Missing, invalid, expired or revoked key | Check the key and header format |
| 402 | Plan limit reached (reports, call minutes, API access) | Upgrade, or wait for the next month |
| 403 | Key lacks the scope, IP not allowlisted, or origin not allowed | Adjust the key in the dashboard |
| 404 | Not found in this workspace | Check the ID. Keys only see their own workspace |
| 409 | Duplicate (e.g. same call externalId) or wrong state | Treat as already done |
| 413 / 415 | Body too large / wrong content type | Send smaller batches, as JSON or multipart |
| 429 | Rate limit exceeded | Back off and retry after the time in the error message |
| 5xx | Our side | Retry with exponential backoff; contact support if it persists |
Rate limits #
| Plan | Secret key requests / minute | AI reports / month | Call minutes / month |
|---|---|---|---|
| Free | No API access | 5 | 60 |
| Starter | 30 | 50 | 600 |
| Professional | 120 | 300 | 3 000 |
| Business | 600 | 2 000 | 15 000 |
Limits are counted per key, over a sliding one-minute window. Public keys are also limited to 30 requests per minute per client IP. Push URLs accept 60 requests per minute.
Asynchronous work #
Reports and call processing take seconds to minutes, so their create endpoints return 202 Accepted with an ID and a status of QUEUED/PENDING. You can poll the resource every 5–10 seconds, or, better, subscribe to webhooks.
Pagination #
/v1/calls is cursor-paginated. Pass limit (1–100), then send the returned nextCursor as cursor until it is null./v1/reports and /v1/datasets return the most recent 100 and 200 items.
let cursor = null;
do {
const url = new URL("https://api.summarix.co.za/v1/calls");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, { headers: { Authorization: `Bearer ${key}` } }).then((r) => r.json());
handle(res.data);
cursor = res.nextCursor;
} while (cursor);Versioning #
The API is versioned in the path (/v1). Within a version we only make additive changes: new endpoints, new optional fields and new response fields. Your client should ignore fields it doesn't know. Breaking changes will ship as /v2, with at least 12 months' notice.