Skip to content

Webhook setup

Webhook setup

1. Register the endpoint in Postal

Postal's admin is web-UI-only (there is no admin API), so this is a manual step per mail server: Postal admin → your mail server → Webhooks → Add webhook, URL:

https://your-app.example/postal/webhook/{server-name}

{server-name} must match your postal.servers key; without it the delivery is attributed to the default server. Subscribe to all events — the package handles every type.

2. Configure the signing key

Postal signs every webhook with its install-wide RSA key. Fetch it as PEM:

php artisan postal:webhook-key
POSTAL_WEBHOOK_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n"

Verification is on by default and fails closed — without the key every delivery is rejected with 401. For local development you can switch it off:

POSTAL_WEBHOOK_VERIFY=false

3. Queueing

The controller acknowledges immediately and processes on your queue. Optionally isolate the work:

POSTAL_WEBHOOK_QUEUE=webhooks
POSTAL_WEBHOOK_CONNECTION=redis

4. Middleware and path

'webhooks' => [
    'path' => 'postal/webhook',   // route: POST {path}/{server?}
    'middleware' => ['api'],
],

The route is named postal.webhook. If your api middleware group applies throttling, make sure Postal's retry bursts fit within it.

5. Prove it

php artisan queue:work &
php artisan postal:tail

Send yourself a message; sent/delivered/opened events appear in the tail as Postal delivers them.