Webhooks
Receiving events
Ndeipi tells your server about every change it makes: decisions on identity checks, deposits arriving, transfers moving, payouts bouncing.
Set up an endpoint
- Register an HTTPS endpoint
POST /webhook_endpointswith your URL and, optionally, the event types you want. Each endpoint gets its own Ed25519 key pair; store the returnedpublic_key_pem. New endpoints startdisabled.curl -X POST "$NDEIPI/webhook_endpoints" \ -H "Api-Key: $NDEIPI_API_KEY" -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "url": "https://api.yourapp.example/ndeipi/webhooks", "event_types": ["transfer.state_changed", "user.kyc_status_changed"] }' - Enable it
Once your receiver verifies signatures, enable it with
PATCH /webhook_endpoints/{webhook_endpoint_id}and{ "status": "enabled" }. A test-delivery call that enables an endpoint automatically is coming soon. - Answer quickly
Return any
2xxwithin 10 seconds, then do the work. Anything else, or no answer, counts as a failure.
Retries and the event log
Failed deliveries are retried with exponential backoff for up to 2 days. After that the event is marked failed, but it stays available for 30 days through GET /events, and POST /events/{event_id}/redeliver sends it again. Each redelivery is signed with a new timestamp.
What a delivery looks like
The body is one event: its type, the kind of object and its object_version, a snapshot of the object after the change in data, and the changed fields' earlier values in previous_attributes. Three headers come with it:
| Header | Example |
|---|---|
Ndeipi-Signature | t=1791302400,v1=ed/v9bqUhRje5vmBt… |
Ndeipi-Event-Id | evt_01JA8ZH3WR2T7D0B8A5Z4Y3X2W |
Ndeipi-Delivery-Attempt | 1 |
Handling events safely
- Verify first. Check the signature over the raw bytes of the body before you parse it. See verifying signatures.
- Deduplicate. The same event can be delivered more than once. Record each event
idyou've processed and skip repeats. - Expect any order. Use
object_versionto ignore a snapshot older than one you've already applied. - Accept the unknown. New event types may be added; acknowledge them with
2xxand ignore them.