Skip to content
UDX
On this page

Rate Limits

Understand shared member rate limits, read rate-limit state in REST headers and WebSocket responses, and throttle before you are rejected.

Request capacity is shared by the member. Every user, account, API key, and connection under that member draws from the same read, write, and cancel buckets, so creating another API key or opening another connection does not increase capacity.

Authenticated REST requests and WebSocket commands both charge these buckets. Some REST operations accept but do not require authentication: an authenticated request charges the member’s read bucket like any other, while an unauthenticated request shares a separate per-client limit and carries no bucket state. Streaming market data never carries bucket state.

A REST request rejected by a rate limit is not saved as an operation’s result. Wait for the advised interval, then retry the same request with a new timestamp and signature, reusing any idempotency key it carried. When a WebSocket command receives an error frame with code: rate_limit_exceeded, it is not saved as an operation’s result; wait for retry_after_ms, then send a new command with a fresh id and the same params. The session was signed at connect, so do not add a per-message signature. For a missing or otherwise unresolved response, follow Asynchronous Writes before retrying.

Read Your Remaining Capacity

Responses for requests that use a bucket include RateLimit-Policy and RateLimit headers for that bucket:

RateLimit-Policy: "read";q=30;w=2
RateLimit: "read";r=12;t=1
  • q is the bucket’s token capacity.
  • w is the number of seconds required to refill an empty bucket.
  • r is the number of tokens remaining after the request.
  • t is the number of seconds until the bucket is full.

Use r to slow requests before receiving a 429. These headers are absent when a request does not use a bucket, including an idempotent replay and a 503.

The field format follows the IETF’s RateLimit header fields for HTTP draft. HTTP 429 Too Many Requests and Retry-After behavior are defined in RFC 6585.

Each command charges the bucket and weight published for it in the WebSocket API. A subscribe command costs more as it names more tickers. The response to a charged command carries a rate_limit object with the state left by that decision:

Field Meaning
bucket The bucket consulted: read, write, or cancel.
capacity The bucket’s token capacity.
refill_tokens_per_minute Tokens restored per minute.
remaining Tokens left after this command.
full_after_ms Milliseconds until the bucket is full if nothing else is admitted.

Use remaining to pace commands. A response that spent no tokens, such as an exact duplicate subscribe, omits rate_limit. Streaming market data never carries it.

Handle a Rejection

When a REST request exhausts its bucket, the exchange returns:

  • 429 Too Many Requests;
  • Retry-After in integer seconds;
  • Cache-Control: no-store; and
  • Problem Details whose type is urn:udx:problem:member-rate-limit-exceeded when the member’s bucket was exhausted, or urn:udx:problem:unauthenticated-rate-limit-exceeded when an unauthenticated request exhausted the public per-client limit.

A 503 Service Unavailable with type: urn:udx:problem:request-admission-unavailable means UDX could not safely evaluate whether to admit the request; it does not mean the member exhausted its capacity. Retry it with bounded exponential backoff and jitter. Do not use the human-readable detail field to decide how to recover.

A rejected command answers with an error frame correlated by your command id:

  • rate_limit_exceeded carries retry_after_ms and the rate_limit state. Wait at least that long before sending the command again.
  • capacity_exceeded means a standing resource is at its limit: in-flight commands, active subscriptions, or market data streams, at connection, member, or process scope. Release resources rather than retrying.
  • admission_unavailable means UDX could not evaluate the command. Retry with bounded backoff.

Check Current Limits

GET /rate_limit_profile returns the member’s bucket capacity, refill rate, and cost per request.