Adopture Docs
API Reference

Error Handling

Error codes, rate limits, and how to handle API errors.

This page covers the error responses returned by the Adopture API, rate limiting behavior, and best practices for handling failures.

HTTP Status Codes

StatusError CodeDescription
202--Events accepted successfully
400validation_failedRequest body does not match the expected schema
400invalid_jsonRequest body is not valid JSON
401invalid_app_keyApp key not found or has an invalid format
402subscription_inactiveSubscription is canceled, unpaid, or paused
402trial_expiredFree trial has ended
405method_not_allowedOnly POST requests are accepted
413payload_too_largeRequest body exceeds 512 KB
415unsupported_media_typeContent-Type must be application/json
429rate_limit_exceededPer-minute rate limit exceeded
429monthly_limit_exceededMonthly event limit exceeded
429daily_limit_exceededDaily event limit exceeded
503service_overloadedServer is temporarily overloaded

Error Response Format

Error responses include a JSON body with the error code and a human-readable message:

{
  "error": "validation_failed",
  "message": "events[0].name is required"
}

Rate Limits

Limits by Plan

PlanEvents/MonthEvents/Minute
Trial10,000200
10K10,000200
100K100,000500
500K500,0002,000
1M1,000,0005,000
2M2,000,0008,000
5M5,000,00015,000

Rate Limit Headers

Every response includes these headers:

HeaderDescription
X-RateLimit-LimitMaximum requests per minute
X-RateLimit-RemainingRemaining requests in the current window
X-RateLimit-ResetUnix timestamp when the window resets

Handling Rate Limits

When you receive a 429 response, check the Retry-After header for the number of seconds to wait before retrying:

HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 200
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705312800

Monthly Limit Behavior

  • Paid plans have a 10% grace buffer above the stated monthly limit. For example, the 100K plan will accept up to 110,000 events before enforcement.
  • Trial plans are enforced at the exact limit with no grace buffer.

Once the monthly limit is reached, the API returns 429 with the monthly_limit_exceeded error code until the next billing cycle.

Idempotency

Include an Idempotency-Key header with a UUID to safely retry failed requests without creating duplicate events:

POST /api/v1/events HTTP/1.1
Content-Type: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

The server remembers idempotency keys for 300 seconds (5 minutes). If a duplicate request is received within that window, the server returns the original response with an additional field:

{
  "status": "accepted",
  "events": 1,
  "deduplicated": true
}

Best Practices

  • Batch events — Send multiple events per request (up to 100) to reduce the number of API calls
  • Use idempotency keys — Always include an Idempotency-Key when retrying requests to avoid duplicate events
  • Respect Retry-After — When rate-limited, wait the indicated number of seconds before retrying
  • Handle 503 gracefully — Queue events locally and retry with exponential backoff when the service is temporarily overloaded

On this page