Errors, pagination, and limits
Reference common API error shape, pagination rules, and request limits.
Handle InstantML API errors, page through large result sets, and stay inside request limits with the rules on this page. All routes accept the same credentials described in API authentication.
Error shape
Every JSON error uses an HTTP status code and at least an error string. Try it by requesting a run that does not exist:
curl -i https://api.instantml.ai/runs/00000000-0000-0000-0000-000000000000 \
-H "Authorization: Bearer instantml_..."{
"error": "run not found"
}Some errors include a stable code:
{
"error": "plan limit exceeded",
"code": "plan_limit_exceeded"
}Most handlers also attach x-request-id.
Common codes
| Code | Meaning |
|---|---|
payment_required | The org needs billing action before writes are accepted |
plan_limit_exceeded | The write would exceed a blocked plan limit |
rate_limit_exceeded | The request exceeded a short-window API rate limit |
api_request_monthly_limit_exceeded | The org reached a monthly API request allowance and does not have billable overage |
warehouse_unavailable | Hosted tenant warehouse is waking or unavailable |
run_search_invalid | The q run-search query has closed but invalid syntax |
run_search_regex_unsupported | Deprecated Node compatibility was asked to evaluate re:/.../ |
warehouse_unavailable uses HTTP 503 and is retryable from a client point of view.
Run-search validation errors use HTTP 400 and include field: "q" plus an optional 1-based position:
{
"error": "Invalid run search: regex is invalid at column 6.",
"code": "run_search_invalid",
"field": "q",
"position": 6
}Pagination and bounds
Every list route returns a bounded page, never the full data set. Expect and handle these patterns:
GET /runsacceptslimitandoffset; pass a largeroffsetto fetch the next page instead of raisinglimitpast its cap.GET /api/runs/summaryandGET /api/runs/{run_id}/logsreturn anext_cursorfield; pass it back ascursorto fetch the next page.- Fetch metric series per run and key with
start_step/end_stepranges and a pointlimit; batched series responses clamp the effective per-run limit so one response stays within the returned-point budget. - Artifact and object list responses cap their page size; narrow by run, kind, or key when you hit the cap.
- Table row contents are not inlined in object envelopes; page them separately through
GET /api/objects/{object_id}/rows. - When a response includes a
truncatedflag or truncation header, narrow the query before treating the result as complete.
Common limits:
| Input or route | Limit |
|---|---|
| Text fields such as names, paths, and tags | 512 bytes |
| Metrics per scalar batch | 1,000 |
| Metric query limit | Default 1,000, max 5,000 |
| Rank metrics per batch | 1,000 metrics for one (run, step, rank) |
| Rank metric world size | 512 ranks |
| Run page limit | Default 100, max 1,000 |
| Run search query | 512 bytes, 32 terms, 64 AST nodes, depth 8 |
| Run search regex | Max 4 regexes, 128 bytes each; regex must not match empty text |
| Per-run searched field text | First 32 KiB per indexed field |
| Batched metric series run IDs | 2,000 |
| Batched metric series response | Max 120,000 returned points |
| Workspace-view payload | 64 KiB |
| Console log lines per batch | 50 |
| Console log message | 16 KiB |
| Console log query limit | Default 250, max 1,000 |
| Object page limit | Default 100, max 500 |
| Object table row limit | Default 100, max 1,000 |
| Artifact list limit | Max 1,000 |
| Side-by-side comparison | Max 50 runs and 5,000 rows |
| Export runs | Max 500 filter-selected runs or 100 selected run IDs |
| Export metric points | Max 100,000 rows |
| Export metric series | Max 25,000 summaries |
| Export attributes | Max 25,000 rows |
| Export artifacts | Max 10,000 rows |
| Export table rows | Max 25,000 rows |
| Export import rows | Max 500 rows |
| Export CSV response | Max 25 MiB |
Ingest limits
Metric ingest batches should stay within the API's documented batch size. High-frequency loops should batch several scalar values into one run.log(...) call instead of sending one request per scalar.
Hosted short-window API rate limits are plan-aware:
| Tier | General rate | Ingest rate | Monthly request allowance |
|---|---|---|---|
| Free | 5 req/sec, burst 30 | 2 req/sec, burst 10 | 500k requests |
| Pro | 50 req/sec, burst 250 | 25 req/sec, burst 125 | 25M requests |
| Premium | 200 req/sec, burst 1000 | 100 req/sec, burst 500 | 150M requests |
Short-window rate-limit responses use HTTP 429, return code: "rate_limit_exceeded", include X-InstantML-RateLimit-Scope: second, and set Retry-After, RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset. Monthly quota responses use code: "api_request_monthly_limit_exceeded" with X-InstantML-RateLimit-Scope: monthly and reset at the next UTC calendar month. The Python SDK retries bounded short-window 429 responses internally and does not retry monthly quota failures.
Idempotency
Process-spool uploaders set Idempotency-Key for metric and console-log event replay. Compatible servers use that key to accept retries safely.