Server Events API
The Server Events API is Apex's server-to-server event ingest. It sits alongside the Web SDK (browser snippet) and Mobile SDK (Capacitor plugin); together they make up Apex's first-party data collection surface.
The Server Events API lets your backend send events to Apex without going through the browser snippet or a mobile SDK. Use it for:
- Stripe / billing webhooks — fire a
purchase_completedwhen an invoice pays, regardless of whether the user was identified in the browser. - CRM-side conversions — when your CRM (HubSpot, Salesforce, …) qualifies a lead as
customer, send the event server-side so Apex stitches it to the original visitorId. - Custom Lambda / cron workflows — anything happening in your backend that's a meaningful conversion.
Endpoint
POST /api/v1/events
Authentication: an org-scoped server API key (apex_sk_…) from Settings → API Keys.
curl -X POST https://app.apex.inc/api/v1/events \
-H "x-api-key: apex_sk_your_key_here" \
-H "idempotency-key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"events": [
{
"type": "purchase_completed",
"visitorId": "vis_abc123",
"data": {
"value": 99,
"currency": "USD",
"order_id": "order_42"
}
}
]
}'
Response
The Server Events API always responds with { data, error, metadata } — the standard Apex API shape.
{
"data": { "received": 1, "duplicates": 0, "errors": [] },
"metadata": {
"projectKey": "prj_yourkey",
"idempotencyKey": "550e8400-e29b-41d4-a716-446655440000",
"batchSize": 1
}
}
Contract rules
- Batch cap: 100 events. Larger batches return
400 batch_too_large. Shard yourself. - Idempotency: send
idempotency-keyon every batch. Re-deliveries with the same key inside a 15-minute window are short-circuited and return{ deduped: true }. We strongly recommend this — Stripe-style retries are normal and you don't want double-counting. x-apex-projectheader. Only required when your org has multiple projects and Apex can't auto-pick one.- Authorization header is accepted too:
Authorization: Bearer apex_sk_…is equivalent tox-api-key.
How the Server Events API fits the rest of Apex
| SDK | Where it runs | What it sees |
|---|---|---|
Web SDK (apex.js snippet + @apex-inc/sdk) | Browser tab | Anonymous visitors, identifies, custom events, web purchases |
| Mobile SDK (Capacitor plugin) | Native iOS / Android | App installs, in-app purchases, device-level identifiers |
| Server Events API (this) | Your backend | Server-side conversions, webhook-driven events, CRM milestones |
The same visitorId works across all three. When the Server Events API receives an event with a visitorId that the Web SDK previously created, the events show up on the same person in the Conversion Loop view.
OpenAPI spec
The machine-readable spec is at openapi/v1-events.yaml in the apex repo. Drop it into Postman, Insomnia, or the openapi-generator CLI to scaffold a client in your language.
Dashboard surface
When events arrive via the Server Events API, the Server Events health card lights up on /dashboard/settings/workspace showing recent volume, last-seen timestamp, and any errors. If the card stays grey for a workspace whose API key was issued, the typical cause is a wrong projectKey header or a revoked key.