Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Request limits

Parcl applies both an API rate limit and an on-chain request budget. A trading client must handle both.

API rate limit

The APIs use token buckets. The sustained rate is how quickly tokens return; the burst is the most unused capacity the bucket can hold.

API and request classScopeSustained rateBurst
REST API, API key or app sessionPer user100 requests/second200 requests
REST API, public endpointPer client IP50 requests/second300 requests
REST API, sign-in or session writePer client IP20 requests/second200 requests
Validator API, GETPer client IP1,000 requests/second2,000 requests
Validator API, POSTPer client IP500 requests/second1,000 requests

Authenticated REST requests also use the applicable client-IP bucket. When a limit is exceeded, the API returns HTTP 429 with a Retry-After header. Route retries for one user or IP through one scheduler.

On-chain request budget

Each active margin account starts with 10,000 standard request units. It earns one more unit per $1 of trading volume:

standard_request_cap = 10,000 + floor(lifetime_volume_usd)

Each chargeable user action consumes one unit. A batch consumes one unit for each action in the batch. When the standard budget is exhausted, the account can submit one standard action every 10 seconds. Valid cancels and genuine reduce-only orders remain available, but the API rate limits above still apply.

A pending account has a standard request cap of zero until it is activated.

Read current state before sending a burst. The example uses devnet. Mainnet uses https://validator.v4.parcl.co.

curl https://v4-api.dev.parcllabs.com/v1/accounts/12/rate-limit
{
  "accountId": 12,
  "cumulativeVolume": "250000000",
  "requestsUsed": "10040",
  "requestsCap": "10250",
  "safetyRequestsCap": "20000",
  "requestsSurplus": "210",
  "lastOverBudgetRequestAt": 0,
  "standardBudgetExempt": false,
  "standardBudgetExemptionReason": null,
  "congestion": {
    "active": false,
    "proposalTxCapacity": 1000,
    "snapshotUtcDay": 20691,
    "priorDayMakerVolume": "0",
    "totalPriorDayMakerVolume": "40744400000",
    "pendingStandardUnits": "0",
    "quota": "0",
    "remaining": "0"
  }
}

Large counters are decimal strings. Poll this endpoint through one scheduler per account.

safetyRequestsCap is an informational threshold. It does not prevent a valid cancel or genuine reduce-only action.

During congestion, a standard request can also consume the account's maker-share quota. Cancels and genuine reduce-only orders remain available.

Throttle responses

Transaction throttles return HTTP 429, Retry-After, and machine-readable fields:

{
  "status": "failed",
  "hash": "0x...",
  "events": [],
  "error": "account 12 request budget exhausted; retry after 9321 ms",
  "errorCode": "request_budget_exhausted",
  "retryAfterMs": 9321
}
errorCodeClient action
request_budget_exhaustedWait for retryAfterMs and reduce quote churn.
congestion_quota_exhaustedWait for retryAfterMs; cancels and reduce-only actions remain available.
account_pending_activationFund the account activation amount before submitting user actions.
known_signer_not_readyWait for retryAfterMs, then refresh account state.
mempool_admission_throttledWait for retryAfterMs, then refresh the rate-limit endpoint.

Treat an unknown error code as retriable when the HTTP status is 429. Honor both Retry-After and retryAfterMs.