PIING
Reading Developers (API and webhooks)Receiving events
Developers (API and webhooks)
- Developer overview
- Webhooks
- Receiving events
- API access
In this guide
- Your endpoint
- Verifying the request
- How delivery and retries work
- Make your handler idempotent
- Responding
Search or browse documentation
Developers (API and webhooks) 3 / 4
Receiving events
How to consume Piing webhooks, including verifying the request, handling retries with backoff, and making your handler safe to call more than once.
This article covers the practical side of consuming Piing events: how to confirm a request is from Piing, how delivery and retries behave, and how to write a handler that copes with repeats.
Your endpoint
Give Piing an HTTPS URL for your webhook destination. Piing sends a POST with a JSON body in the envelope described in Webhooks. The request carries a User-Agent of Piing-Integration-Delivery.
Your endpoint should:
- Read the JSON body.
- Verify the request, as below.
- Do its work, or queue it, quickly.
- Return a
2xx status to confirm receipt.
Verifying the request
When you set up a webhook destination you can configure an authentication header. Piing sends that header with every delivery, so your endpoint can confirm the caller. A common pattern is a shared secret in an Authorization header, for example a bearer token that only you and Piing know.
In your handler, check that the header is present and matches the secret you configured before you trust the body. Reject anything that does not match.
Tip
Keep the secret out of source control and rotate it if you suspect it has leaked. You can update the destination's auth header at any time.
How delivery and retries work
Piing records every delivery and tracks its outcome. If a delivery fails in a way that is worth retrying, it is rescheduled automatically with an increasing delay.
- The retry schedule is roughly 1 minute, 5 minutes, 15 minutes, 1 hour, 4 hours, then 12 hours, capped at 24 hours, with a little random jitter so retries do not arrive in lockstep.
- After 6 attempts a delivery is marked as dead lettered and is not retried again.
Whether a failure is retried depends on what went wrong:
- Network errors and timeouts are retried.
- A
5xx response from your endpoint is retried.
- A
429 rate limit response is retried.
- A
4xx response such as 401, 403 or 404 is treated as a client error and is not retried.
So if your endpoint is temporarily down, return a 5xx or simply fail, and Piing will try again. If you return a 4xx, Piing assumes the request will never succeed and stops.
There is also a per destination delivery rate limit, so a sudden burst is smoothed out rather than delivered all at once.
Make your handler idempotent
Because deliveries can be retried, your endpoint may receive the same event more than once. Design for it:
- Use a stable field from the payload as a de-duplication key. For a check-in,
properties.checkinId is a good choice. For an attributed purchase, the combination of orderId and checkinId works.
- Record which keys you have already processed, and ignore a repeat.
- Make the side effect safe to apply twice, for example an upsert rather than a blind insert.
This way a retry after a slow response, or a network blip, does not double count.
Responding
Return a 2xx as soon as you have safely accepted the event. If your processing is slow, accept the event, queue it, and return success straight away, rather than holding the connection open and risking a timeout that triggers a retry.
If deliveries to your endpoint are not arriving, check that the URL is reachable over HTTPS, that you are returning a 2xx, and that the event type you expect is enabled on the destination. For anything you cannot resolve, contact us.
Related guides
Was this guide helpful?
Next guide in Developers (API and webhooks)
API access
Piing's supported developer surface is the outbound event stream. There is no public self-serve REST API today; broader access is available by request.
Still need a hand? Contact us