Skip to content
GridRouterhome

Search

Search providers, capabilities and pages

Docs

Errors

One error envelope for every route and MCP tool, with stable codes, HTTP statuses and what to do about each.

Every error, from every route and MCP tool, has the same shape:

{
  "error": {
    "code": "vendor_key_required",
    "message": "Add your Hunter key in Settings → Vendor keys. GridRouter runs Hunter on your own key.",
    "request_id": "req_…",
    "call_id": "call_…",
    "details": { "provider": "hunter" }
  }
}
FieldMeaning
codeStable and machine-readable. Branch on this, never on message
messageHuman-readable; may change
request_idQuote it to support
call_idPresent when a call was created; it is in your logs
retry_after_msWhen to retry; 429 responses also send Retry-After
detailsCode-specific context: issues with field paths on validation errors, layer on rate limits, the partial run on waterfall stops

A vendor that answered but found nothing is not an error: the call succeeds with hit: false.

Codes

StatusCodeMeaning
400invalid_metameta must be up to 16 string values (500 chars) under [A-Za-z0-9_.-]{1,40} keys.
400invalid_requestThe body, query or a header failed validation.
401unauthorizedNo API key, or the key is unknown, revoked or expired.
402insufficient_balanceThe wallet cannot hold the call's maximum cost.
402max_cost_exceededThe quoted price is above max_cost_micro (or X-Grid-Max-Cost).
403account_frozenThe organization is on a dispute or fraud hold.
403budget_blockedA key, app or workspace budget is spent for the period.
403plan_limit_reachedA plan limit (keys, workspaces, drains, retention) is reached.
403scope_deniedThe key lacks the scope this route needs, or the IP is not on its allowlist.
404not_foundNo such endpoint, capability or resource in this workspace.
409cancelledThe run was cancelled by the caller.
409conflictThe request conflicts with the resource's current state.
422idempotency_mismatchAn Idempotency-Key was reused with a different body.
422strict_filtersStrict provider filters (only, ignore, no fallbacks, max price) left no endpoint.
422validation_failedA definition or input failed validation; details.issues has field paths.
429rate_limitedA rate limit was hit; wait retry_after_ms or the Retry-After seconds.
500internal_errorSomething failed on our side; the request_id identifies it.
502response_buffer_limitThe vendor's response was larger than the gateway buffers.
502upstream_errorThe vendor returned an error; details.upstream_status has its status.
503grid_saturatedThe gateway is shedding load; retry after the hint.
503provider_capacity_unavailableThe vendor's concurrency or rate budget is exhausted right now.
504deadline_exceededA waterfall hit its total deadline; the partial result is in details.
504upstream_timeoutThe vendor did not answer within the timeout.

Retrying

  • Retry with backoff: 429 (after retry_after_ms), 503 and 502/504 from a vendor. A routed /v1/run has already tried the other vendors before returning one of these.
  • Fix the request: 400, 404, 409, 422.
  • Fix the account or key: 401, 402, 403. Retrying cannot help.

Failed calls are never charged.

Idempotency

Send Idempotency-Key on any POST that runs something: 8 to 128 characters of letters, digits and _ . : -.

  • The same key with the same body returns the stored first response, free.
  • The same key with a different body is 422 idempotency_mismatch.
  • The same key while the first request is still running is 409.
  • Streaming responses and 5xx errors are not stored, so the key is released and you can retry.