pex

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_completed when 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-key on 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-project header. 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 to x-api-key.

How the Server Events API fits the rest of Apex

SDKWhere it runsWhat it sees
Web SDK (apex.js snippet + @apex-inc/sdk)Browser tabAnonymous visitors, identifies, custom events, web purchases
Mobile SDK (Capacitor plugin)Native iOS / AndroidApp installs, in-app purchases, device-level identifiers
Server Events API (this)Your backendServer-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.