---
title: "Events — Webhooks for Laravel | Roundly"
description: "Seven events for your audit log — received, rejected, processing failed, delivered, failed, endpoint disabled, secret rotated — and how to listen safely."
url: https://roundly-consulting.com/open-source/docs/webhooks-for-laravel/events
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Webhooks for Laravel](https://roundly-consulting.com/open-source/docs/webhooks-for-laravel.md)

# Events

In RoundlyConsulting\\Webhooks\\Events, all final readonly; none carries a secret, a signature or a raw body. Write your audit log from them:

| Event | When | Carries |
| --- | --- | --- |
| `WebhookReceived` | On the worker, before the handler — on every attempt of a run | webhook (InboundWebhook: sanitized payload, delivery id, endpoint, isReplay, run, attempt; isFirstAttempt()) |
| `WebhookRejected` | A request to a known endpoint was refused (steps 2–8); rate-limited rejections once per window | endpointId, reason (RejectionReason), status, ip, userAgent |
| `WebhookProcessingFailed` | A handler failed on its last try, or the endpoint was deleted before the delivery ran | delivery, errorCode (handler\_failed / endpoint\_deleted) |
| `DeliverySucceeded` | A 2xx answer | delivery, attempt |
| `DeliveryFailed` | Every failed attempt | delivery, attempt, final, nextAttemptAt |
| `EndpointDisabled` | Auto (consecutive failures, 410) or by hand | endpoint (outbound), reason (DisableReason) |
| `EndpointSecretRotated` | A rotation | endpoint, direction, graceEndsAt |

Unknown keys fire nothing, so a stranger cannot spam your listeners; a duplicate fires nothing.

## Once per attempt — WebhookReceived

WebhookReceived fires on every attempt of a run — a handler that throws is retried, and the retry fires it again. A listener that must act once per delivery checks the attempt:

```php
Event::listen(function (WebhookReceived $event): void {
    if (! $event->webhook->isFirstAttempt()) {
        return;   // a retry of a run whose handler threw
    }

    Cache::increment('webhooks.received.'.$event->webhook->type);
});
```

## Queued listeners

WebhookProcessingFailed, DeliverySucceeded, DeliveryFailed, EndpointDisabled and EndpointSecretRotated use SerializesModels: a ShouldQueue listener receives the models as they are when it runs. WebhookReceived carries the sanitized payload, and a queued listener on it would write that payload into your queue store unencrypted, around payloads.encrypt. Keep WebhookReceived listeners synchronous, or queue only the delivery id and load the delivery in the job:

```php
Event::listen(function (WebhookReceived $event): void {
    SyncInvoice::dispatch($event->webhook->deliveryId);   // the job loads it again
});

// in SyncInvoice::handle()
$delivery = Webhooks::inbound()->deliveries()->where('public_id', $this->deliveryId)->firstOrFail();
```

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/webhooks-for-laravel.md)
