Ludex ingestion — error catalog
This document describes HTTP status codes and error payloads for the ingestion API (/v1/ingest/event, /v1/ingest/batch). Use it for client logic and retry decisions.
Response shapes
Structured errors (JSON object in body)
Many errors return a JSON object:
{
"status": "error",
"code": "<machine-readable code>",
"message": "<human-readable explanation>"
}
Note: Some failures use a plain string body (see 400, 422, 413, 500 below). Clients should accept either a JSON object or a string for error bodies.
Success
| Endpoint | Status | Meaning |
|---|---|---|
POST /v1/ingest/event |
202 | Event accepted (or deduplicated; see duplicate on success model) |
POST /v1/ingest/batch |
202 | Batch fully or partially processed |
Batch may return status: "partial" with per-index errors (still 202).
Errors by status code
400 — Bad request (malformed JSON)
| Field | Value |
|---|---|
| When | Request body is not valid JSON. |
| Body | Plain string: Invalid JSON body |
| Retryable | No — fix the payload encoding. |
401 — Unauthorized
code |
When | Retryable |
|---|---|---|
auth_failed |
Missing/invalid Authorization header (not Bearer <token>), unknown key, hash mismatch, inactive credential, revoked key, expired key |
No |
Headers: WWW-Authenticate: Bearer is set for 401 responses.
Client action: Obtain a valid key; do not retry the same secret in a tight loop.
403 — Forbidden (credential valid but request not allowed)
code |
When | Retryable |
|---|---|---|
project_mismatch |
Body project_id does not match the project bound to the API key |
No |
environment_mismatch |
Body environment does not match the environment id on the API key |
No |
insufficient_scope |
Credential is missing ingest:events (single endpoint) or ingest:batch (batch endpoint) |
No |
Client action: Fix project_id / environment to match the key, or request a key with the correct scopes.
413 — Payload too large
413 is returned when either the HTTP request body is too large or, on batch ingest only, the events array is too long.
Request body byte limit (single and batch)
| Field | Value |
|---|---|
| When | Request body exceeds 10 MiB (10 485 760 bytes). |
| Body | Plain string, e.g. Request body too large. Maximum size is 10485760 bytes. |
| Retryable | No — shrink the JSON payload. |
Batch event count (batch only)
| Field | Value |
|---|---|
| When | events array length exceeds 5000. |
| Body | Plain string, e.g. Batch too large. Max 5000 events per request. |
| Retryable | No — split into smaller batches. |
422 — Unprocessable entity (validation)
| Field | Value |
|---|---|
| When | JSON parses but fails validation for the request model. |
| Body | Plain string prefix: Invalid request body: … (details vary). |
| Retryable | No — correct required fields, types, and shapes per contract-reference.md. |
429 — Too many requests (rate limit)
| Field | Value |
|---|---|
| When | Per-client rate limit exceeded. |
| Limits (defaults) | Single: 1000/minute; batch: 100/minute. |
| Body | JSON error message (treat as opaque). |
| Retryable | Yes — backoff and retry with jitter; respect Retry-After if present. |
500 — Internal server error
| Endpoint | When | Body | Retryable |
|---|---|---|---|
POST /v1/ingest/event |
Server-side processing failure after accept pipeline | Plain string: Failed to queue event |
Yes (with backoff); use Idempotency-Key for stable replay |
POST /v1/ingest/batch |
Per-event failures appear as 202 partial with errors[]; widespread failure may surface as 5xx |
Varies | Yes with caution |
Client action: Retry with Idempotency-Key and exponential backoff. Reuse a stable event_id when retrying so deduplication can apply.
503 — Service unavailable
| Field | Value |
|---|---|
| When | GET /v1/ready reports service dependencies not ready. |
| Retryable | Yes (health checks / orchestration). |
Batch partial errors (202, status: "partial")
Each entry in errors has:
index— zero-based index in the requesteventsarraycode— string (e.g.internal_error,validation_error)message— explanation
Retryable: Depends on code. Treat internal_error as retryable for that index; treat validation-like codes as non-retryable until the event payload is fixed.
Quick reference table
| Status | Typical cause | Retry? |
|---|---|---|
| 400 | Invalid JSON | No |
| 401 | Auth failed | No |
| 403 | Scope / project / environment mismatch | No |
| 413 | Body over 10 MiB, or batch over 5000 events | No — shrink body or batch |
| 422 | Schema validation | No |
| 429 | Rate limit | Yes — backoff |
| 500 | Server failure | Yes — backoff + idempotency |
202 partial |
Some batch rows failed | Per errors[].code |
For request/response models and headers, see contract-reference.md.