DocsAPI

Limits, retries & errors

Rate limits, safe retries with Idempotency-Key, and what every error looks like.

Rate limits#

Only reads are rate-limited. Buys, sells, batches, launches and every other write are not throttled — the spending guardrails are the key's own scopes and caps (maxSolPerTrade, dailySolCap, the wallet list), not a per-minute bucket.

Reads are counted per minute, per key and per account. Many keys on one account share the account's limit.

Kind of callPer keyPer account
Reads (GET)300600
Writes and launchesno limitno limit

A read answer carries the key's bucket in three headers (writes carry none — there is no bucket):

Header
X-RateLimit-LimitReads per minute the key allows
X-RateLimit-RemainingReads left in the current minute
X-RateLimit-ResetWhen the bucket is full again, as a Unix time in seconds

Over the limit you get 429 with a Retry-After header (seconds), and the same number in the body:

{ "code": "rate_limited", "error": "rate limit reached — slow down", "retryAfterSeconds": 12, "traceId": "…" }

Wait that long before trying again. Too many calls with a wrong or revoked key from one address are refused with 429 and code: "auth_rate_limited" for a minute.

Retry safely#

Networks drop answers. To retry a buy, sell, batch or launch without doing it twice, send an Idempotency-Key header: a unique string you pick per operation, 8–128 characters of letters, digits, -, _ or :.

curl -X POST https://evm.vortexdeployer.com/evm/api/v1/buy \
  -H "Authorization: Bearer vd_…" \
  -H "Idempotency-Key: buy-2026-09-15-0001" \
  -H "Content-Type: application/json" \
  -d '{"mint":"7xKX…pump","walletId":"812","amountSol":0.05}'
You send againYou get
Same key, same bodyThe first call's answer. Nothing is sent twice
Same key, same body, first call still running409 with code: "operation_pending". Ask again shortly
Same key, different body409 with code: "idempotency_conflict". Use a new key for a new operation
A key outside 8–128 characters or with other characters400 with code: "invalid_idempotency_key"
Always use it for money

Without Idempotency-Key, a retry is a new trade.

Errors#

Every error is JSON with three fixed fields:

{ "code": "insufficient_scope", "error": "this API key does not have the 'trade' scope", "traceId": "9f1c…" }
Field
codeA stable, machine-readable name for the refusal (table below). Switch on this
errorWhat went wrong, for people. The wording may change; the code won't
traceIdQuote it in a support ticket

Some codes add a field naming the limit that refused you: over_trade_cap sends maxSolPerTrade, over_daily_cap sends dailySolCap, wallet_not_allowed sends walletId, rate_limited sends retryAfterSeconds.

A malformed body is validation_failed and lists each problem with its path:

{
  "code": "validation_failed",
  "error": "validation failed",
  "details": [{ "path": "amountSol", "message": "Too small: expected number to be >0" }],
  "traceId": "…"
}

Codes#

CodeStatusMeans
validation_failed400The body or query is malformed. details lists every problem. Fix it; retrying won't help
bad_request400Understood but refused, e.g. a delayed sell batch, or buys on an EVM launchpad
invalid_idempotency_key400The Idempotency-Key header is malformed
invalid_api_key401Missing, wrong or revoked key
insufficient_scope403The key doesn't have the scope this route needs
ip_not_allowed403The call came from outside the key's IP allowlist
key_restricted403A key with limits tried something only an unlimited key may do (tasks, a real launch)
sandbox_key403A sandbox key sent a real (dryRun: false) call
wallet_not_allowed403The wallet isn't yours, or isn't on the key's wallet list
private_key_not_allowed403A wallet-list key sent a privateKey
over_trade_cap403A buy above the key's Max per buy
over_daily_cap403The buy would pass the key's Daily cap
not_found404No such route, or the task, project or wallet isn't yours
idempotency_conflict409Same Idempotency-Key, different body
operation_pending409Same Idempotency-Key, first call still running. Ask again shortly
conflict409The change clashes with the current state
payload_too_large413The body is over the size limit
unprocessable422Understood but impossible, e.g. selling a token the wallet doesn't hold
rate_limited429Over the rate limit. Honour Retry-After
auth_rate_limited429Too many bad keys from this address. Wait a minute
internal_error500Our side. Retry with the same Idempotency-Key, and quote the traceId
service_unavailable503Briefly unavailable, or an idempotent operation is being reconciled. Retry with the same Idempotency-Key

Every status and code, per route, is in the OpenAPI document.

Request an API feature#

APIRequests files a feature request. Replies arrive on the ticket and in the bell.