Skip to content

Email provider webhooks

Inbound delivery webhooks for API mail providers (Postmark, Mailgun). SMTP / log / array / sendmail do not support webhooks.

Endpoints

ScopeMethodPath
CentralPOST/webhooks/email/{provider}
Tenant (custom mail)POST/webhooks/email/{provider}/{tenant}

{provider} is the driver slug (postmark, mailgun). {tenant} is the Stancl tenant string id (UUID).

Both routes are CSRF-exempt (webhooks/email/*) and rate-limited (throttle:webhooks).

Feature flag

EnvDefaultPurpose
EMAIL_WEBHOOKS_ENABLEDtrueMaster switch (503 when false)
EMAIL_WEBHOOK_TOLERANCE300Mailgun signature timestamp skew (seconds)

Settings

Central system_settings / Tenant tenant_settings:

KeyTypeNotes
mail_webhook_secretencrypted stringPostmark Basic Auth password / Mailgun signing key
mail_webhook_eventsJSON arrayPlatform event keys to process

Admin GET settings responses include meta.mail_webhook with webhook_url, available_events, selected_events, instructions, and has_webhook_secret.

Tenant mail_mode=system does not expose a tenant webhook URL — configure Central.

Platform event keys

Drivers advertise a catalog; the UI multiselect stores these keys:

delivered, bounced, complained, opened, clicked, failed

Defaults when unset: delivered, bounced, complained, opened, clicked.

Processing

  1. Resolve driver via EmailDriverRegistry (SupportsWebhooks).
  2. Verify signature with the scoped webhook secret.
  3. Parse provider payload → normalized events.
  4. Filter by mail_webhook_events.
  5. Match CentralEmailLog / TenantEmailLog by message_id and update status / meta (idempotent via meta.webhook_event_ids).

Status progression

Typical path: sendingsentdeliveredopenedclicked.

  • Open/Click webhooks set status to opened / clicked (and increment meta.opens / meta.clicks).
  • Engagement statuses are not downgraded back to delivered.
  • Terminal statuses (bounced, complained, failed) are not overwritten by open/click.

Provider tracking requirements

Selecting Open/Click in Central/Tenant settings only controls which inbound events SaleOS processes. You must also enable Open/Click on the provider webhook and turn on open/link tracking in the provider console (e.g. Postmark server tracking). Settings save does not sync checkboxes into Postmark/Mailgun.

Extending a new provider

  1. Implement EmailDriverInterface + SupportsWebhooks.
  2. Register in config/email.phpdrivers.
  3. Advertise webhookEvents(), verifySignature(), parseEvents(), setupInstructions().
  4. No controller or UI branching on provider name is required beyond the driver catalog.

Official documentation for the SaleOS SaaS Platform.