Errors and Rate Limits
Error format
Section titled “Error format”All API errors return a JSON response with a consistent structure:
{ "error": "unauthorized", "message": "Invalid or expired API token.", "timestamp": "2025-01-15T14:30:00.000Z", "path": "/api/PurchaseDocuments/my", "requestId": "req_abc123def456"}| Field | Description |
|---|---|
error | Machine-readable error code |
message | Human-readable description of the problem |
timestamp | When the error occurred (ISO 8601) |
path | The requested API path |
requestId | Unique request identifier — include this in support requests |
HTTP status codes
Section titled “HTTP status codes”| Code | Meaning | When it happens |
|---|---|---|
200 | OK | Request succeeded |
204 | No Content | Resource exists but is still processing (e.g., a document being parsed) |
401 | Unauthorized | Missing, invalid, or expired API token |
403 | Forbidden | Token does not have the required scope for this endpoint |
404 | Not Found | The requested resource does not exist |
429 | Too Many Requests | Rate limit exceeded — slow down and retry |
Rate limits
Section titled “Rate limits”Each token scope has a per-hour request limit:
| Scope | Hourly limit |
|---|---|
read | 1,000 requests |
write | 2,000 requests |
admin | 5,000 requests |
The rate limit window resets on a rolling hourly basis.
Rate limit headers
Section titled “Rate limit headers”Every API response includes headers that tell you your current rate limit status:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum number of requests allowed per hour |
X-RateLimit-Remaining | Number of requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the rate limit window resets |
X-RateLimit-Reset-After | Seconds until the rate limit window resets |
When you receive a 429 response, an additional header is included:
| Header | Description |
|---|---|
Retry-After | Seconds to wait before making another request |
Handling rate limits
Section titled “Handling rate limits”Here is a recommended approach for handling rate limits:
-
Monitor the
X-RateLimit-Remainingheader on every response. If it drops below a threshold (e.g., 50), slow down your request rate. -
On a
429response, read theRetry-Afterheader and wait that many seconds before retrying. -
Implement exponential backoff for retries. If the first retry also fails, wait progressively longer.
Example in bash:
response=$(curl -s -w "\n%{http_code}" \ "https://api.ogarni.ai/api/weekly-summaries/latest" \ -H "X-API-Key: $OGARNIAI_API_TOKEN")
http_code=$(echo "$response" | tail -1)
if [ "$http_code" = "429" ]; then echo "Rate limited. Waiting before retry..." sleep 60fiSee Code examples for more complete implementations with rate limit handling in Python and JavaScript.