Webhook Delivery
Webhook deliveries are processed asynchronously via Laravel's queue system. This ensures that webhook dispatching does not block the main request and can handle retries gracefully.
DeliverWebhook Job
The DeliverWebhook job is a queued job responsible for sending the HTTP POST request to the webhook endpoint:
DeliverWebhook::dispatch($webhook, $event, $payload);
- Sends a POST request to the webhook's
url - Includes the JSON payload in the request body
- Signs the payload with HMAC-SHA256 and sets the
X-Signatureheader - Records the delivery result (success or failure)
- Updates the webhook's
last_triggered_attimestamp
Dispatching Events
Use the WebhookDispatcher service to trigger webhook deliveries from anywhere in your application:
use App\Services\WebhookDispatcher;
WebhookDispatcher::dispatch($organizationId, 'member.joined', [
'user_id' => $user->id,
'name' => $user->name,
'role' => 'member',
]);
The dispatcher finds all enabled webhooks for the organization that are subscribed to the given event (or to *) and queues a DeliverWebhook job for each one.
WebhookDelivery Model
Each delivery attempt is recorded in the WebhookDelivery model:
webhook_id— the webhook that was triggeredevent— the event nameresponse_status— HTTP status code from the endpoint (e.g. 200, 500)success— boolean indicating whether the delivery succeeded (2xx status)delivered_at— timestamp of the delivery attempt
Delivery History
The system stores the last 50 deliveries per webhook. Older records are automatically pruned. View delivery history via the API:
GET /api/organizations/{org}/webhooks/{id}/deliveries
{
"data": [
{
"id": 1,
"event": "member.joined",
"response_status": 200,
"success": true,
"delivered_at": "2026-03-21T14:30:01Z"
},
{
"id": 2,
"event": "api_key.created",
"response_status": 500,
"success": false,
"delivered_at": "2026-03-21T14:25:00Z"
}
]
}