Endpoint
POST /api/ingest
Reports are submitted to the ingest service’s /api/ingest path. The
SDKs are preconfigured with the host and handle this call for you — you only need
the raw API when building a custom client.
Authentication
Authenticate with your app’s SDK key as a bearer token:
Authorization: Bearer <your-sdk-key> An invalid or missing key returns 401 with { "error": "invalid_sdk_key" }.
Request body
The request is multipart/form-data: one part is the JSON
envelope, and up to five further parts are binary
attachments (screenshot, recording, …) referenced from the envelope. The envelope
part may be gzip-compressed.
Limits
| Limit | Value |
|---|---|
| Total request size | 25 MB |
| Decompressed envelope | 5 MB |
| Files per request | 6 (envelope + up to 5 attachments) |
| Rate limit (per SDK key) | 60 requests / minute |
| Rate limit (per source IP) | 200 requests / minute |
Response
On success the API returns 200 with:
{
"status": "received",
"eventId": "<uuid>",
"deliveryCount": 2,
"idempotent": false
} eventId— the stored event’s id.deliveryCount— how many subscribers the report is being fanned out to.idempotent—trueif this exact report was already received (a retried submission), so it was de-duplicated rather than re-delivered.
Errors
| Status | Error | Meaning |
|---|---|---|
401 | invalid_sdk_key | Missing or invalid bearer token. |
413 | payload_too_large | Request or envelope exceeded a size limit. |
429 | rate_limit_exceeded | Too many requests; honour the Retry-After header. |
Idempotency. The ingest API de-duplicates repeated submissions of
the same report across the retention window, so an SDK retry after a flaky network
never fans the report out twice.