Docs

Backend events API

Send signups, purchases, errors and deploys from your own backend. They roll up into daily metrics and show up as markers on your change timeline. Your ingest key and ingest secret are on your app's Connectors → Backend events page.

Endpoint

POST https://whyitchanged.com/ingest/<ingest_key>/events
Content-Type: application/json

Authentication

Use either one:

Request body

An object with an events array (a bare array or a single event also works). Up to 500 events and 1 MB per request.

{"events": [
  {"type": "signup", "user_id": "u_123", "ts": "2026-11-01T10:00:00Z", "channel": "web"},
  {"type": "create_tap", "user_id": "u_123"},
  {"type": "purchase", "user_id": "u_123", "id": "evt_1", "amount": 14.99, "net": 10.49,
   "product_id": "pack_1499", "transaction_id": "2000000123"},
  {"type": "error", "user_id": "u_123", "message": "Export failed: timeout"},
  {"type": "purchase_failed", "user_id": "u_123", "message": "SKErrorUnknown"},
  {"type": "push_campaign", "title": "New templates push", "detail": "4,800 recipients"},
  {"type": "deploy", "title": "api v1.8.2", "id": "deploy-182"}
]}

Event types

Fields

Example

curl -X POST https://whyitchanged.com/ingest/$INGEST_KEY/events \
  -H "Authorization: Bearer $INGEST_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"events":[{"type":"deploy","title":"api v1.8.2","id":"deploy-182"}]}'

A successful response returns counts of the accepted events. Invalid events are reported per index, and the rest still go through.

Other inbound webhooks