HTTP status codes
| Code | Meaning | Action |
|---|
200 | Event accepted | No action needed |
400 | Bad request — missing field, invalid format, or inactive site_id | Fix the request payload |
401 | Missing X-API-Key header | Add the X-API-Key header |
403 | Invalid key, revoked key, or site_id/key mismatch | Check your API key and site_id |
413 | Payload too large | Reduce payload size or split into smaller batches |
422 | Validation error — see response body for details | Fix the specific field error |
429 | Rate limit exceeded | Back off and retry after the Retry-After header value |
500 / 502 / 503 | Server error | Retry with exponential backoff |
All error responses return a JSON body with details:
For 400 errors with a single message:
Rate limits
| Endpoint | Limit | Scope |
|---|
POST /ct (browser events) | 100 requests / min | Per IP address |
POST /collect/batch | 100 requests / min | Per IP address |
POST /server-events | 1,000 requests / min | Per API key |
POST /server-events/batch | 1,000 requests / min | Per API key |
Short bursts above the limit are handled with a small grace window. Design your clients to back off on 429 rather than relying on burst tolerance.
Error handling pattern
For server events
Retry logic
Only retry on transient errors. Stop immediately on permanent errors.
| Retry? | Status codes |
|---|
| Yes — retry with backoff | 429, 500, 502, 503, 504, network timeout |
| No — fix the request | 400, 401, 403, 413, 422 |
See Idempotency & Retries for a full retry implementation with exponential backoff.
Common 422 causes
| Error | Fix |
|---|
scan_session_id invalid format | Must be a valid UUID (e.g. 7ad26d4f-3181-4ef8-b6ca-b8f59499dd43) |
event_name missing | Required for server events |
conversion_value.currency invalid | Must be a 3-letter ISO 4217 code (e.g. USD, EUR, GBP) |
properties too large | Keep under 10 KB |
Raw email in properties | Use user_identifiers.email_hash with a SHA-256 hash instead |