Rate Limits
Rate limiting policy for the Oathe API — what's limited, what's not, and how to handle 429 responses.
What Is Limited
Rate limits apply only to audit submissions (POST /api/submit). Two limits are enforced per IP address:
| Rule | Threshold |
|---|---|
| Cooldown between submissions | 60 seconds |
| Sliding window cap | 75 submissions per 5 hours |
The cooldown prevents burst submissions. The sliding window prevents sustained abuse over longer periods. Most workflows only need one submission at a time, followed by polling or WebSocket for results.
What Is Not Limited
All read-only endpoints are unrestricted:
GET /api/audit/{audit_id}GET /api/skill/{owner}/{repo}/latestGET /api/skill/{owner}/{repo}/summaryGET /api/audits/search
You can poll status, fetch reports, and query summaries as frequently as needed.
Deduplicated Requests
If you submit a repository URL that is already queued or currently being audited, Oathe returns the existing audit_id instead of creating a new audit. This deduplicated response does not count against your rate limit.
{
"audit_id": "existing-abc123",
"status": "processing",
"deduplicated": true
}
This means retrying a submission for the same repo is safe and free.
429 Response Format
When the rate limit is exceeded, the API responds with HTTP 429 Too Many Requests:
{
"statusCode": 429,
"name": "rate_limited",
"message": "Rate limited. Please wait before retrying."
}
The response includes a Retry-After header with the number of seconds to wait before the next allowed submission:
HTTP/1.1 429 Too Many Requests
Retry-After: 45
Content-Type: application/json
Handling 429 in Code
import time
import requests
response = requests.post(
"https://audit-engine.oathe.ai/api/submit",
json={"skill_url": "https://github.com/owner/repo"}
)
if response.status_code == 429:
wait = int(response.headers.get("Retry-After", 60))
time.sleep(wait)
response = requests.post(
"https://audit-engine.oathe.ai/api/submit",
json={"skill_url": "https://github.com/owner/repo"}
)
Best Practice
Before submitting a new audit, check whether a recent result already exists:
GET https://audit-engine.oathe.ai/api/skill/{owner}/{repo}/summary
If the summary endpoint returns a current (non-stale) result, you may not need to submit at all. This avoids unnecessary submissions and keeps you well within the rate limit.