Errors, pagination, and limits

Reference common API error shape, pagination rules, and request limits.

Open .md

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:

bash
curl -i https://api.instantml.ai/runs/00000000-0000-0000-0000-000000000000 \
  -H "Authorization: Bearer instantml_..."
json
{
  "error": "run not found"
}

Some errors include a stable code:

json
{
  "error": "plan limit exceeded",
  "code": "plan_limit_exceeded"
}

Most handlers also attach x-request-id.

Common codes

CodeMeaning
payment_requiredThe org needs billing action before writes are accepted
plan_limit_exceededThe write would exceed a blocked plan limit
rate_limit_exceededThe request exceeded a short-window API rate limit
api_request_monthly_limit_exceededThe org reached a monthly API request allowance and does not have billable overage
warehouse_unavailableHosted tenant warehouse is waking or unavailable
run_search_invalidThe q run-search query has closed but invalid syntax
run_search_regex_unsupportedDeprecated 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:

json
{
  "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 /runs accepts limit and offset; pass a larger offset to fetch the next page instead of raising limit past its cap.
  • GET /api/runs/summary and GET /api/runs/{run_id}/logs return a next_cursor field; pass it back as cursor to fetch the next page.
  • Fetch metric series per run and key with start_step/end_step ranges and a point limit; 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 truncated flag or truncation header, narrow the query before treating the result as complete.

Common limits:

Input or routeLimit
Text fields such as names, paths, and tags512 bytes
Metrics per scalar batch1,000
Metric query limitDefault 1,000, max 5,000
Rank metrics per batch1,000 metrics for one (run, step, rank)
Rank metric world size512 ranks
Run page limitDefault 100, max 1,000
Run search query512 bytes, 32 terms, 64 AST nodes, depth 8
Run search regexMax 4 regexes, 128 bytes each; regex must not match empty text
Per-run searched field textFirst 32 KiB per indexed field
Batched metric series run IDs2,000
Batched metric series responseMax 120,000 returned points
Workspace-view payload64 KiB
Console log lines per batch50
Console log message16 KiB
Console log query limitDefault 250, max 1,000
Object page limitDefault 100, max 500
Object table row limitDefault 100, max 1,000
Artifact list limitMax 1,000
Side-by-side comparisonMax 50 runs and 5,000 rows
Export runsMax 500 filter-selected runs or 100 selected run IDs
Export metric pointsMax 100,000 rows
Export metric seriesMax 25,000 summaries
Export attributesMax 25,000 rows
Export artifactsMax 10,000 rows
Export table rowsMax 25,000 rows
Export import rowsMax 500 rows
Export CSV responseMax 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:

TierGeneral rateIngest rateMonthly request allowance
Free5 req/sec, burst 302 req/sec, burst 10500k requests
Pro50 req/sec, burst 25025 req/sec, burst 12525M requests
Premium200 req/sec, burst 1000100 req/sec, burst 500150M 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.

Next steps