Error Handling¶
This document describes error responses and handling patterns as implemented in the Integration API.
HTTP Status Codes¶
| Code | Meaning | Typical Cause |
|---|---|---|
| 200 | OK | Successful GET or list |
| 201 | Created | Resource created |
| 202 | Accepted | Request accepted (e.g., test event) |
| 204 | No Content | Successful DELETE or revoke |
| 400 | Bad Request | Validation failed |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Valid auth but insufficient permissions |
| 404 | Not Found | Resource does not exist |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Unexpected server error |
| 503 | Service Unavailable | System contention |
Error Response Format¶
Error responses return JSON with an error field:
{
"error": "Description of what went wrong"
}
Additional fields may be present depending on context.
Validation Errors (400)¶
Missing Required Fields¶
{
"error": "Name is required"
}
{
"error": "type is required"
}
{
"error": "At least one event type is required."
}
Invalid Values¶
{
"error": "Invalid URL."
}
{
"error": "Invalid cursor."
}
{
"error": "Unknown query parameter."
}
Size Limits¶
{
"error": "payload exceeds maximum size of 262144 bytes (got 300000 bytes)"
}
{
"error": "URL exceeds maximum length of 500 characters (got 600 characters)"
}
JSON Validation¶
{
"error": "payload must be valid JSON"
}
Event Type Validation¶
{
"error": "Event type 'unknown.event' is not configured for this subscription",
"subscribedEventTypes": ["client.created", "payment.succeeded"]
}
{
"error": "Event type 'bad.type' does not have a sample payload generator",
"hint": "This event type may be valid but sample generation is not yet implemented"
}
Authentication Errors (401)¶
Returned when authentication is missing or invalid:
- Missing X-Api-Key header
- Invalid API key format
- API key not found
- API key has been revoked
Authorization Errors (403)¶
Returned when authentication succeeds but operation is not permitted: - API key lacks required scope - Attempting to access another company's resources
Tool-Managed Subscription Error¶
{
"error": "This subscription is managed by Zapier and cannot be edited here. Use Zapier to manage it.",
"managed_by": "Zapier",
"is_tool_managed": true
}
Not Found Errors (404)¶
{
"error": "Event not found."
}
For security, 404 is also returned when a resource exists but belongs to a different company.
Rate Limit Errors (429)¶
Response Format¶
{
"error": "Rate limit exceeded",
"retryAfter": 12,
"limit": 60,
"window": "1m",
"policy": "read:60/1m",
"resetUtc": "2026-01-24T18:45:32.000Z",
"currentUsage": 61
}
Response Headers¶
Successful requests include rate limit headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1737739532
X-RateLimit-Window: 1m
X-RateLimit-Policy: read:60/1m
Rate Limit Buckets¶
| Bucket | Default Limit | Endpoints |
|---|---|---|
read |
60/minute | GET /events, searches |
write |
100/minute | POST/PATCH/DELETE operations |
admin |
200/minute | /events/test, webhook ops |
System Contention (503)¶
{
"error": "Rate limit check busy",
"reason": "lock_timeout",
"retryAfter": 1,
"message": "Rate limiting backend is experiencing high contention. Please retry after the specified delay."
}
This is not a rate limit violation. The system is temporarily busy. Retry after 1-2 seconds.
Server Errors (500)¶
{
"error": "An error occurred while creating the API key"
}
{
"error": "Failed to generate sample payload"
}
{
"error": "Unable to encrypt signing secret"
}
Retry Recommendations¶
Safe to Retry¶
- 429 (Rate Limited) - After
retryAfterseconds - 503 (Service Unavailable) - After 1-2 seconds
- Network timeouts
- Connection failures
Not Safe to Retry Without Modification¶
- 400 (Bad Request) - Fix the request first
- 401 (Unauthorized) - Fix authentication
- 403 (Forbidden) - Obtain required permissions
- 404 (Not Found) - Resource does not exist
Best Practices¶
Respect Rate Limit Headers¶
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
time.sleep(retry_after + 2)
Check Remaining Before Bulk Operations¶
Monitor X-RateLimit-Remaining header to avoid hitting limits during batch operations.
Use Idempotency Keys¶
For POST operations creating resources, include deduplication keys to handle safe retries.