Delivery & Retry
YorAuth delivers webhooks asynchronously via a queue. This page describes the delivery process, retry schedule, auto-disable behavior, and how to inspect delivery history.
How Delivery Works
When an event fires, YorAuth:
- Creates a
WebhookDeliveryrecord for each active webhook subscribed to that event. - Enqueues a background job (
DispatchWebhookJob) to perform the HTTP request. - Re-validates the webhook URL against DNS (SSRF protection) immediately before sending.
- Sends a
POSTrequest to your endpoint with the event payload and signature headers. - Records the HTTP response status, response body (up to 5000 characters), and duration in milliseconds.
Your endpoint must return a 2xx HTTP status code within 30 seconds. Any other response (including connection errors and timeouts) is treated as a failure.
Retry Schedule
If a delivery attempt fails, it is retried automatically up to 3 total attempts with the following backoff:
| Attempt | Delay Before Retry |
|---|---|
| 1st attempt | Immediate |
| 2nd attempt | 30 seconds after 1st failure |
| 3rd attempt | 5 minutes after 2nd failure |
| Final failure | 30 minutes after 3rd failure (no further retries) |
The total retry window is approximately 35 minutes from the first attempt. After all 3 attempts are exhausted without a successful 2xx response, the delivery is marked as permanently failed.
SSRF Protection at Delivery Time
Before each delivery attempt, YorAuth re-resolves the webhook URL's hostname via DNS and confirms all resolved IP addresses are public. If the hostname has resolved to a private or reserved IP (a potential DNS rebinding attack), the delivery is blocked immediately and marked as permanently failed — it is not retried. This is a security event rather than a connectivity problem, so it does not count toward the auto-disable threshold.
Auto-Disable Behavior
To prevent hammering unreachable endpoints, YorAuth automatically disables a webhook when it accumulates too many consecutive delivery failures (across all retries exhausted).
When a webhook reaches its failure_threshold of consecutive failures, it is:
- Set to
is_active: false - Timestamped with
auto_disabled_at
To re-enable the webhook after investigating and fixing the issue, set is_active: true via the update endpoint:
curl -X PUT https://api.yorauth.com/api/v1/applications/{applicationId}/webhooks/9d4e1a2b-... \
-H "Authorization: Bearer your-api-key" \
-H "Content-Type: application/json" \
-d '{"is_active": true}'
When a delivery succeeds, the consecutive_failures counter resets to zero.
Delivery Logs
Every delivery attempt is recorded. You can retrieve the 50 most recent deliveries for a given webhook:
GET /api/v1/applications/{applicationId}/webhooks/{webhookId}/deliveries
curl https://api.yorauth.com/api/v1/applications/{applicationId}/webhooks/9d4e1a2b-.../deliveries \
-H "Authorization: Bearer your-api-key"
Response 200 OK:
{
"data": [
{
"id": "ab12cd34-ef56-7890-abcd-ef1234567890",
"event": "user.created",
"response_status": 200,
"delivered_at": "2026-02-25T12:00:01+00:00",
"retry_count": 0,
"created_at": "2026-02-25T12:00:00+00:00"
},
{
"id": "bc23de45-fg67-8901-bcde-fg2345678901",
"event": "role.assigned",
"response_status": 500,
"delivered_at": null,
"retry_count": 2,
"created_at": "2026-02-25T11:30:00+00:00"
}
]
}
Delivery fields:
| Field | Description |
|---|---|
id | UUID for this delivery. Matches X-YorAuth-Delivery-Id in the request header. |
event | The event type that triggered this delivery. |
response_status | HTTP status code returned by your endpoint. null if a connection error occurred. |
delivered_at | Timestamp of successful delivery. null if not yet delivered or permanently failed. |
retry_count | Number of retry attempts made (0 = first attempt succeeded or failed without retry). |
created_at | When the delivery was initially created. |
Delivery Statistics (Dashboard)
The dashboard API provides aggregate statistics for a webhook:
GET /api/dashboard/applications/{applicationId}/webhooks/{webhookId}/stats
Response 200 OK:
{
"data": {
"total_deliveries": 1240,
"successful": 1235,
"failed": 5,
"success_rate": 99.6,
"avg_duration_ms": 87,
"consecutive_failures": 0,
"failure_threshold": 10,
"auto_disabled_at": null
}
}
HTTP Requirements for Your Endpoint
| Requirement | Detail |
|---|---|
| Method | POST |
| Success status | Any 2xx (200–299) |
| Timeout | Respond within 30 seconds |
| Protocol | HTTPS only |
| Content-Type | YorAuth sends application/json |
Troubleshooting Failed Deliveries
Endpoint not reachable
Check that your server is publicly accessible and that firewall rules allow inbound HTTPS traffic. Remember that YorAuth validates the URL DNS during delivery — ensure your hostname resolves to a public IP from external DNS.
Signature verification failing
Ensure you are computing the HMAC over the raw request body bytes, not a parsed/re-serialized object. See Security for correct verification code examples.
Responses timing out
Your endpoint must respond within 30 seconds. If your handler is slow, acknowledge the webhook immediately (return 200 OK) and process the event asynchronously in a background queue.
Webhook was auto-disabled
Check the auto_disabled_at field and delivery history to identify when failures began. Fix the underlying issue, then re-enable the webhook by setting is_active: true.
Testing your endpoint
Use the dashboard test endpoint to send a webhook.test event on demand without waiting for a real event to occur. See Setup.