Webhooks
Test your endpoint
Send test events, replay deliveries and develop on your own computer.
You don't have to wait for an invoice to be paid to know your endpoint works.
Send a test event
In Developers › Webhooks, open an endpoint and choose Send a test event. Or ask the API, optionally with a catalog event to get a realistic sample:
curl https://app.getoatmilk.com/api/v1/accounting/webhooks.test \
-H "Authorization: Bearer $OATMILK_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"endpointId": "5d4c3b2a-1f0e-4d9c-8b7a-6e5f4d3c2b1a",
"eventType": "invoice.paid"
}'Test deliveries are signed like real ones and appear in the delivery log, but they never count towards turning an endpoint off.
Watch the delivery log
Every delivery, with its payload, your server's status code, how long it took and a short excerpt of its answer, is in the delivery log in Developers › Webhooks and in webhooks.deliveries.list. Delivery rates and response times over time are in Developers › Usage and webhooks.deliveries.stats. Retry a failed delivery from there, or with webhooks.deliveries.retry, once your server is fixed.
curl -G https://app.getoatmilk.com/api/v1/accounting/webhooks.deliveries.list \
-H "Authorization: Bearer $OATMILK_API_KEY" \
--data-urlencode 'status=failed' \
--data-urlencode 'limit=20'Develop on your own computer
While you develop, an endpoint can point at http://localhost. To receive real deliveries from staging, expose your local server with a tunnel such as ngrok or cloudflared and add its https:// address as an endpoint.
To test your signature check without Oatmilk at all, sign a sample with your own secret in the signature playground and send it with the curl command it gives you. The timestamp is current, so your tolerance check passes.
A checklist before going live
- The endpoint answers
2xxwithin a few seconds, before slow work. - It verifies
Oatmilk-Signatureagainst the raw body and refuses anything older than 300 seconds. - It stores each event
idand skips duplicates. - It reads the record from the API when the order of events matters.
- It answers
200to event types it doesn't recognise. - The signing secret is stored like a password, and rotating it is a documented step.