Skip to content

Rate limits

Darwin applies rate limiting per tenant, distinguishing between read and write API calls, and between on-chain capture events and outbound webhook deliveries. This page describes the per-tier quotas and the expected client behavior when approaching the limit.

Current tiers. The numbers below are representative and apply per tenant, not per user.

TierRequests / minRequests / monthCapture events / monthWebhook deliveries / month
Sandbox (evaluation)60100,0005,00025,000
Starter (early production)3001,000,00050,000250,000
Growth (mid-scale)1,50010,000,000500,0002,500,000
Scale (high volume)7,500100,000,0005,000,00025,000,000
EnterpriseCustom quotasCustom quotasCustom quotasCustom quotas

Write calls (event prepare, custody transfers, recalls) consume both request quota and the specific capture events quota. Read calls (NFT queries, lineage, operational reports) only consume request quota.

Every API response includes headers with your current quota state:

HeaderMeaning
X-RateLimit-LimitMax requests per minute in your tier
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets
Retry-AfterWhen 429 is returned, seconds to wait before retrying

When a request exceeds the per-minute limit, the API responds with HTTP 429 Too Many Requests and a JSON body describing which limit was hit:

{
"error": "rate_limit_exceeded",
"scope": "requests_per_minute",
"retryAfter": 12
}

The client should:

  1. Read Retry-After (seconds) or X-RateLimit-Reset (timestamp).
  2. Wait at least that long before retrying.
  3. Apply exponential backoff with jitter if 429s persist, to avoid thundering herd when the window expires.

Monthly quotas (requests, capture events, webhook deliveries) reset on the first UTC day of the calendar month. If a monthly quota is exhausted, the API returns 429 with scope: "requests_per_month", scope: "events_per_month", or scope: "webhooks_per_month" as appropriate.

Outbound webhook deliveries do not consume your inbound request quota. They have their own monthly quota per tier (the Webhook deliveries / month column above). If your receiver endpoint replies with 429, Tracium honors the Retry-After header and retries within the 3-attempt exponential backoff policy.

Moving from Sandbox to Starter, Starter to Growth, Growth to Scale, or any tier to Enterprise is arranged with the commercial team. Enterprise quotas are written into the contract and may include:

  • Higher burst rates per minute.
  • Monthly quotas with no cap or an agreed cap.
  • Priority in the webhook queue.
  • Support and availability SLAs.

Contact the team at tech@darwinevolution.io with your current tier, projected usage, and time horizon. We will respond with the recommended quota and next steps.

  • Batch by idempotency: Captia uses client-generated idempotent UUIDs. Retrying a lost event creates no duplicates and consumes no extra quota if the server already processed it.
  • Cache on read: NFT inventory, ancestry, and operational report queries support aggressive client-side caching. Canonical metadata does not change after on-chain anchoring.
  • GraphQL for composed queries: a single well-formed GraphQL query consumes one request rather than several REST calls. Useful for dashboards.
  • Respect Retry-After: never retry before the indicated value. Premature retries count against your quota and extend the block window.