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-Signature header
  • Records the delivery result (success or failure)
  • Updates the webhook's last_triggered_at timestamp

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 triggered
  • event — the event name
  • response_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"
        }
    ]
}