Inbound webhook

POST events to Pivolio from any backend.

The inbound webhook is the general-purpose server-side source. If a system can make an authenticated HTTPS POST, it can feed events into your workspace — a CRM marking a lead qualified, an order-management system confirming a shipment, a cron job replaying yesterday’s conversions.

Set it up

1

Create the source

Go to Integrations and open Inbound webhook, then Generate write key. This mints a write key that belongs to this source alone — it is not your SDK write key.

2

POST your events

Send each event to /ingest/integration with the key in the X-Write-Key header. There is nothing else to configure — no signing setup, no callback URL to register.

3

Verify

The wizard’s Verify step waits for your first event, and the Live Debugger shows every event that arrives, which person it resolved to, and how each destination handled it.

Authentication

The write key is the only credential on this endpoint.

There is no request signing and no HMAC. Anyone holding this write key can write events into your workspace. Treat it as a secret: store it in your server’s secret manager, never ship it to a browser, and never commit it.

This is the opposite of the first-party SDK write key, which is designed to be public because it can only ingest events from a browser context. The two keys are not interchangeable — presenting an SDK write key to /ingest/integration returns 403.

Example request

Four fields are required on every event. Omitting any of them returns a 422:

  • event_id — a unique ID for this event; used for deduplication. A ULID works well.
  • event_name — matches ^[a-zA-Z0-9_.]{1,128}$. Prefer a standard name so destinations can map it.
  • event_time — Unix time in seconds (a float is fine). Milliseconds will place your event decades into the future.
  • anonymous_id — the visitor ID. Forward the one the browser SDK established when you have it.
$curl -X POST 'https://api.pivolio.com/ingest/integration' \
> -H 'X-Write-Key: wk_live_xxxxxxxxxxxx' \
> -H 'Content-Type: application/json' \
> -d '{
> "event_id": "01HQZX9K2M4N6P8R0T2V4W6Y8Z",
> "event_name": "order_completed",
> "event_time": 1700000000,
> "anonymous_id": "anon_6f1c2b0e-9a3d-4c8e-b1f7-2d5a8c9e0b31",
> "user_id": "user_456",
> "traits": { "email": "jane@acme.com", "phone": "+15551234567" },
> "properties": { "order_id": "ord_123", "revenue": 99.5, "currency": "USD" }
> }'

A success returns {"ok": true, "event_id": "...", "duplicate": false}. Resend the same event_id and you get "duplicate": true — the event is not counted or delivered twice, which makes retries safe.

Send raw email and phone values in traits. Pivolio normalizes and hashes them server-side so every destination receives byte-identical digests; hashing them yourself is the fastest way to quietly destroy your match rates.

Rotating the key

Creating the webhook source again rotates its key — the same Generate write key action, exposed as Rotate key once a key exists. The old key stops working immediately, so deploy the new one to your backend in the same change. Remove source deactivates the key entirely.

  • Integrations — every available source.
  • JavaScript SDK — the browser source that establishes the anonymous_id you should forward here.