Ingestion API — overview & auth
The ingestion API is the wire contract every Whisperr SDK implements. It’s three endpoints. If an SDK exists for your stack, use it — it handles batching, retries, and idempotency for you. This reference is for everyone else.
Base URL: https://api.whisperr.netEndpoints
Section titled “Endpoints”| Endpoint | Body | Notes |
|---|---|---|
POST /v1/events/batch |
{ "events": [ <event>, … ] } |
≤ 500 events per batch |
POST /v1/events/track |
<event> |
single event |
POST /v1/identify |
<identify> |
traits + contact channels |
Prefer /v1/events/batch — it’s what all SDKs use. /v1/events/track exists
for one-off calls (curl, webhooks, low-volume scripts).
See Track events and Identify users for the body schemas, and Delivery, retries & idempotency for how to handle responses.
Authentication
Section titled “Authentication”Every request sends your app’s ingestion key (wrk_…, from the dashboard →
Developer → API Keys). Either header is accepted:
X-API-Key: wrk_...Authorization: Bearer wrk_...The ingestion key is publishable — it ships in client bundles and can only ingest events for your app. Treat it like a PostHog project key, not a secret.
Example
Section titled “Example”curl -X POST https://api.whisperr.net/v1/events/track \ -H "Content-Type: application/json" \ -H "X-API-Key: $WHISPERR_API_KEY" \ -d '{ "external_user_id": "user_8842", "event_type": "payment_failed", "occurred_at": "2026-06-14T12:00:00.000Z", "properties": { "amount_cents": 4900 }, "context": { "$message_id": "f7a1c2e0-4b3d-4f6a-9c1e-8d2b5a7e3f10" } }'Strictness
Section titled “Strictness”The API validates strictly and rejects unknown fields — a misspelled field
name fails the whole request with a 4xx rather than being silently ignored.
This is deliberate: it keeps every SDK honest against the same contract, and
it means a 2xx always means the data landed exactly as specified.