Skip to content

Getting started

Errors and rate limits

The error format, every status code the API returns, per-minute rate limits and monthly quotas.

Error format

Every error from an endpoint that takes a key has the same JSON body, and the status code is also the HTTP status. Match on the status code; the message is for people and can change.

FieldDescription
errorstringrequiredHuman-readable message. Match on the status code, not on this text.
statusintegerrequiredThe HTTP status code, repeated.
timestampstringrequiredWhen the error was produced.date-time
Example error
{
  "error": "Insufficient permissions. Required scope: ai:query",
  "status": 403,
  "timestamp": "2026-10-23T14:02:11.093Z"
}

Status codes

StatusMeaning
200Success.
307Redirect to an OAuth provider (GET /oauth/{provider} only).
400The request is invalid: a missing field, a value out of range, an unsupported provider. The message says which.
401The key is missing, malformed, unknown or revoked; the account has no active plan; or the key has used its monthly quota.
403The key lacks the scope, is a test key on trade execution, or the account is not on the plan the endpoint needs.
410The provider has been switched off (Coinbase).
429The key hit its per-minute rate limit.
500Something failed on our side, or the body was not valid JSON (see below).
503GET /health only: the database is unreachable.

Authentication errors

Every endpoint that takes a key checks it first, in this order, before reading the request body. The first failing check decides the response. The last row is the fallback when a check itself fails.

StatusWhenerror
401No Authorization header.Missing Authorization header. Include "Authorization: Bearer enton_live_xxx" or "Authorization: Bearer enton_test_xxx"
401The header does not start with "Bearer ".Invalid Authorization format. Use "Bearer enton_live_xxx" or "Bearer enton_test_xxx"
401The token does not start with "enton_".Invalid API key format. Keys must start with "enton_live_" or "enton_test_"
401No active key matches.Invalid or inactive API key
401The account that owns the key has no active Trader or Partner plan (a trial counts).Active subscription required. Please upgrade your plan at https://enton.ai/pricing
429The key made its per-minute limit of requests in the last 60 seconds. Sent with Retry-After: 60.Rate limit exceeded. Please wait before making more requests.
401The key has used its monthly quota. Quotas reset at 00:00 UTC on the first of the month.Monthly quota exceeded. Please upgrade your plan or wait until next month.
401The key lookup itself failed.Internal server error during authentication

Two of these are 401 where you might expect another code: an account without a plan, and a key over its monthly quota. Read the message to tell them apart from a bad key.

Rate limits

Each key has a per-minute limit set by its plan. The API counts the key's requests in the 60 seconds before each new one; when that count has reached the limit, the request gets 429 with Retry-After: 60.

PlanRequests per minuteRequests per month
Free101,000
Trader6050,000
Partner120No limit

Responses to authenticated requests carry these headers:

HeaderMeaning
X-RateLimit-LimitRequests per minute allowed for this key.
X-RateLimit-RemainingRequests left in the current 60-second window.
X-RateLimit-ResetISO 8601 time 60 seconds after this request.
X-API-Key-NameThe name you gave the key. Sent on successful authentication only.
X-API-Key-TierThe plan the key was created under. Sent on successful authentication only.
Retry-AfterSeconds to wait. Sent with 429 only, always 60.

Monthly quota

Each key also has a monthly request quota (none on Partner). It resets at 00:00 UTC on the first day of each month. A key over its quota gets 401 with Monthly quota exceeded until the reset. No header reports the quota; the developer portal shows each key's usage.

What counts as a request

  • A request that passes the authentication checks counts once toward both the rate limit and the quota, whatever happens next. A 400, a 403 for a missing scope or a 500 still counts.
  • A request refused during authentication, including a 429, does not count.
  • GET /health and GET /openapi.json take no key and never count.

Retrying

  • 429: wait for Retry-After seconds, then retry.
  • 500 and 503: retry with exponential backoff and a cap. Each retry counts toward your limits.
  • 400, 401, 403 and 410: do not retry. Fix the request, key, scope or plan first.
  • Trade execution: never retry an execute call blindly after a timeout. Check the order in your broker account first, then prepare again if you need to.

Known quirks

  • A body that is not valid JSON gets 500, not 400.
  • An error from an internal service can be passed through with that service's status code and message, so you may see a status not listed for an endpoint. Treat any other 4xx as not retryable and any other 5xx as retryable.
  • Some endpoints currently fail with 401 after your key is accepted. See the known issues.