Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rate Limits

Odin Scan enforces rate limits to ensure fair usage and maintain service reliability. Limits vary by subscription plan and endpoint.

Scan Quotas

PlanScan QuotaPeriod
Basic10 scansPer month
Pro60 scans per seatPer month

Pro scan quotas are pooled at the organization level. For example, a team with 2 Pro seats gets 120 scans per month shared across all members.

General API Requests

Standard read endpoints (listing analyses, checking status, fetching results) have higher limits to support polling workflows:

PlanLimitPeriod
Basic100 requestsPer hour
Pro1,000 requestsPer hour

Rate Limit Headers

Every API response includes rate limit information in the response headers:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1705312800
HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed in the current window
X-RateLimit-RemainingNumber of requests remaining in the current window
X-RateLimit-ResetUnix timestamp (seconds) when the rate limit window resets

Exceeding the Limit

When you exceed a rate limit, the API returns a 429 Too Many Requests response:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705316400
Retry-After: 3600
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again later."
  },
  "timestamp": "2025-01-15T10:30:00Z",
  "requestId": "req-abc123"
}

The Retry-After header indicates how many seconds to wait before making another request.

Best Practices

Poll with backoff. When checking analysis status, start with a 5-second interval and increase to 15-30 seconds as the analysis progresses. Avoid polling more frequently than once per second.

# Good: poll every 10 seconds
while true; do
  status=$(curl -s https://api.odinscan.ai/api/v1/analysis/$ID/status \
    -H "Authorization: Bearer $API_KEY" | jq -r '.status')
  if [ "$status" = "completed" ] || [ "$status" = "failed" ]; then
    break
  fi
  sleep 10
done

Use webhooks instead of polling. When creating an analysis, provide a webhookUrl to receive a notification when the analysis completes. This eliminates the need for status polling entirely.

{
  "repositoryUrl": "https://github.com/username/repo",
  "webhookUrl": "https://your-server.com/webhook/odinscan"
}

Cache results locally. Analysis results do not change after completion. Fetch the result once and store it locally rather than requesting it repeatedly.

Monitor your usage. Check the X-RateLimit-Remaining header in responses to track how close you are to the limit. If you are consistently approaching the limit, consider upgrading your plan.

Batch operations where possible. Instead of syncing repositories one by one, use the full sync endpoint (POST /api/v1/repositories/sync) which handles all repositories in a single request.

Upgrading Your Plan

If you consistently hit rate limits, consider upgrading your subscription. See Subscription Plans.

Next Steps