API Referencev1

Rate Limits

The Odento API enforces rate limits to ensure fair usage and platform stability. Limits are applied per API key using a sliding window algorithm. All rate-limited responses include headers that tell you your current usage and when limits reset.

Default Limits

Every API key has a default rate limit of 100 requests per minute. This limit is configurable per key in the developer portal and can be increased based on your plan.

PlanRate LimitMonthly Quota
Free100 req/min10,000 req/month
Starter200 req/min100,000 req/month
Professional500 req/min1,000,000 req/month
EnterpriseCustomCustom

Rate limits are applied per API key, not per IP address. If you need higher limits, contact support or upgrade your plan in the developer portal.

Rate Limit Headers

Every API response includes headers that describe your current rate limit status. Check these headers to proactively manage your request rate:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets
X-Quota-LimitMonthly request quota
X-Quota-RemainingRequests remaining in the current month
X-Quota-ResetISO 8601 date when the monthly quota resets

Example Response Headers

Requesthttp
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1732701300
X-Quota-Limit: 10000
X-Quota-Remaining: 8456
X-Quota-Reset: 2025-02-01T00:00:00Z

Rate-Limited Response (429)

When you exceed the rate limit, the API returns a 429 Too Many Requests status with the RATE_LIMITED error code. The response includes a Retry-After header indicating how many seconds to wait before retrying:

Response429json
{
  "success": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded. Maximum 100 requests per minute."
  }
}
Retry-After: 23

Monthly Quota System

In addition to per-minute rate limits, each API key has a monthly request quota. When the quota is exhausted, the API returns a 403 Forbidden with the QUOTA_EXCEEDED error code:

Response403json
{
  "success": false,
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "Monthly request quota of 10000 has been exceeded. Quota resets on 2025-02-01."
  }
}

Quotas reset on the first day of each month at midnight UTC. You can monitor your quota usage via the X-Quota-Remaining header or in the developer portal dashboard.

Handling 429 Responses

When you receive a 429 response, stop sending requests immediately and wait for the rate limit window to reset. Here's a recommended retry pattern with exponential backoff and jitter:

Requestjavascript
async function rateLimitedRequest(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const response = await fetch(url, options)
    const body = await response.json()

    if (response.status === 429) {
      if (attempt === maxRetries) {
        throw new Error('Rate limit exceeded after ' + maxRetries + ' retries')
      }

      // Get wait time from Retry-After header (seconds)
      const retryAfter = parseInt(response.headers.get('Retry-After') || '1')

      // Add jitter to avoid thundering herd
      const jitter = Math.random() * 0.5
      const waitMs = (retryAfter + jitter) * 1000

      console.log('Rate limited. Waiting ' + waitMs + 'ms before retry...')
      await new Promise(r => setTimeout(r, waitMs))
      continue
    }

    return body
  }
}

Best Practices

  • Monitor headers proactively. Check X-RateLimit-Remaining on every response and throttle before hitting the limit.
  • Use exponential backoff with jitter. When you do get rate-limited, retry with increasing delays plus random jitter to avoid synchronized retry storms.
  • Cache responses. If your data doesn't change frequently, cache it client-side to reduce API calls.
  • Batch operations. Where possible, use bulk endpoints instead of making individual requests for each item.
  • Respect the Retry-After header. Never retry immediately after a 429 — always wait the specified duration.
  • Use webhooks instead of polling. Subscribe to events instead of repeatedly checking for changes.
  • Spread requests evenly. Avoid burst patterns — distribute requests across the minute window.

Need Higher Limits?

If your integration requires higher rate limits or monthly quotas, contact our team at api@odento.app or upgrade to a higher plan in the developer portal.

Was this page helpful?

Help us improve our documentation