What counts as success
Pazy treats a delivery as successful only when your endpoint returns a2xx status within the timeout. Everything else is a failure:
- Any
3xx,4xxor5xxstatus. Redirects are not followed. - No response within the timeout. The default is 10 seconds and the maximum is 30.
- A connection, DNS or TLS error.
- A response body larger than 64 KB.
- A URL that fails the URL requirements.
200 or 204 with an empty body as soon as you’ve stored the event.
Retry schedule
A failed delivery is retried with exponential backoff and about ±10% random jitter, for up to 5 attempts in total.
Retries are picked up by a scheduler that polls every 30 seconds by default, so an attempt can start somewhat later than the nominal delay.
After the fifth failed attempt, Pazy stops. The delivery is marked as exhausted and is not sent again automatically.
Handle duplicates
Delivery is at-least-once. The same event can reach you more than once, for example when your200 is lost on the network and Pazy retries. The event id is the same on every attempt.
- Before processing, look up
idin a table or cache of handled events. - If it’s there, return
200and do nothing else. - If not, process the event and record the
id. Do both in one database transaction where you can.
payment.* events, you can also dedupe on data.paymentId, which is unique per payment.
Don’t rely on ordering
Events can arrive out of order. A retry of an older event can land after a newer one has already been delivered. For example, you might seeexpense.approval.status_changed for APPROVED before an earlier retry for PENDING.
- Compare timestamps to decide which event is newer: the envelope’s
createdAt, orpaymentDateonpayment.*events (it isnullon failures and reversals). - Treat status fields as the latest known state only if the event is newer than what you already hold.
- When correctness matters, fetch the current record by
idwith the API.
Respond fast, process later
Your handler holds up Pazy’s delivery while it runs, and a slow response risks a timeout and a duplicate.1
Verify
Check the signature.
2
Persist
Save the raw event, or push it onto a queue such as SQS, RabbitMQ or a jobs table.
3
Acknowledge
Return
200 right away.4
Process
A background worker does the real work, and retries on its own failures.
Return the right status
A
4xx response is also retried. Pazy doesn’t treat any non-2xx status as permanent, so don’t return 400 for events you simply don’t care about.Differences from API retries
The retry rules in Errors and retries apply to requests you send to Pazy. Webhook retries are Pazy retrying requests to you, on the fixed schedule above. They don’t honorRetry-After headers.