OneHop Docs

Rate limits & errors

Understand rate-limit policies, retries, and the gateway error contract.

OneHop applies its own rate-limit policy on top of upstream provider limits. The policy governs requests per minute and concurrent streams per account, and is resolved per request — your key's policy first, then your account's, then the platform default.

Handling 429

When you exceed a limit, the gateway returns RATE_LIMITED with HTTP 429 in the error shape of the entry protocol.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded"
  }
}

Back off and retry

Treat 429 as transient. Retry with exponential backoff and jitter rather than hammering the endpoint. If you consistently hit limits, contact support about a higher policy tier.

Error shape per protocol

Errors are returned in the shape of the family you called, so your existing SDK error handling keeps working:

  • /v1/* and /responses — OpenAI error shape.
  • /anthropic/* and /v1/messages — Anthropic error shape.
  • /vertex-ai/* — Gemini / Google error shape.

Gateway error reference

ErrorHTTPMeaning
API_KEY_REQUIRED401No API key was sent.
INVALID_API_KEY401Key does not exist or was revoked.
AMBIGUOUS_API_KEY400More than one key header was sent.
USER_BLOCKED403The owning account is disabled.
INSUFFICIENT_CREDITS422Wallet balance is below the floor.
RATE_LIMITED429RPM, concurrency, or policy limit hit.
MODEL_NOT_FOUND404No such model in the catalog.
MODEL_PROTOCOL_NOT_SUPPORTED400Model doesn't support that protocol.
MODEL_TEMPORARILY_UNAVAILABLE503Published model is paused, not removed.
SUB2API_POOL_UNAVAILABLE503No upstream capacity available.
UPSTREAM_TIMEOUT504Upstream timed out.
UPSTREAM_ERROR502Upstream returned a 5xx.

Idempotency

Send an X-Idempotency-Key header to make a request safe to retry:

curl https://api.onehop.ai/v1/chat/completions \
  -H "Authorization: Bearer $ONEHOP_API_KEY" \
  -H "X-Idempotency-Key: idem_2026_06_19_001" \
  -H "Content-Type: application/json" \
  -d '{ "model": "openai/gpt-4o-mini", "messages": [{ "role": "user", "content": "hi" }] }'
  • If a request with the same key is still in flight, you get IDEMPOTENCY_IN_PROGRESS (409) and the upstream is not called again.
  • If it already completed, you get IDEMPOTENCY_REPLAY_UNAVAILABLE (409) — the request is not re-billed, but the original response body is not replayed.

Idempotency keys are scoped to your account and prevent double-billing across retries and reconciliation.