AsyncAPI description of the outbound webhook surface for Brevo (formerly Sendinblue). Brevo delivers event notifications by issuing HTTP POST requests with a JSON body to a URL configured by the customer. There are two distinct webhook product lines: - Transactional webhooks: events for transactional email (and SMS) sent through Brevo's SMTP/API relay. - Marketing webhooks: events for marketing email campaigns and for contact-list lifecycle activity. Each event carries an `event` discriminator field whose value identifies the event class (for example `request`, `delivered`, `hard_bounce`, `click`, `unique_opened`, `list_addition`, `contact_updated`). Source documentation: - Transactional webhooks: https://developers.brevo.com/docs/transactional-webhooks - Marketing webhooks: https://developers.brevo.com/docs/marketing-webhooks - Webhooks overview: https://developers.brevo.com/docs/how-to-use-webhooks Security: Brevo does not document an HMAC signature header or a fixed signing secret for outbound webhooks. The documented hardening options are (1) embedding HTTP Basic credentials in the webhook URL and (2) restricting the subscriber endpoint to Brevo's published source IP ranges. Both options are modelled below in `components.securitySchemes`.
Subscriber endpoint that receives Brevo transactional email webhook events. Brevo POSTs one event per HTTP request. The `event` field in the JSON body identifies the event class.
/brevo/marketing/webhook
publishreceiveMarketingWebhook
Receive a Brevo marketing webhook event
Subscriber endpoint that receives Brevo marketing webhook events. Brevo POSTs one event per HTTP request. The `event` field in the JSON body identifies the event class. Marketing webhooks cover both campaign activity (opens, clicks, bounces, unsubscribes) and contact-list lifecycle activity (list additions, contact updates, contact deletes).
Messages
✉
TxRequest
Transactional Sent (request)
A transactional email was accepted by Brevo for sending.
✉
TxDelivered
Transactional Delivered
A transactional email was accepted by the recipient mail server.
✉
TxSoftBounce
Transactional Soft Bounce
A transactional email was temporarily rejected by the recipient mail server.
✉
TxHardBounce
Transactional Hard Bounce
A transactional email was permanently rejected by the recipient mail server.
✉
TxBlocked
Transactional Blocked
A transactional email was blocked before sending (for example, the recipient is on the account-level block list).
✉
TxInvalidEmail
Transactional Invalid Email
The recipient address was rejected as syntactically invalid.
✉
TxDeferred
Transactional Deferred
The recipient mail server temporarily deferred the message; Brevo will retry.
✉
TxError
Transactional Error
A processing error occurred while handling the transactional message.
✉
TxSpam
Transactional Spam Complaint
The recipient flagged the transactional message as spam.
✉
TxOpened
Transactional Opened
The recipient opened the transactional message (may fire multiple times).
✉
TxUniqueOpened
Transactional First Open (unique_opened)
The recipient opened the transactional message for the first time.
✉
TxProxyOpen
Transactional Proxy Open
The transactional message was opened via a mail-privacy proxy (for example Apple Mail Privacy Protection).
✉
TxUniqueProxyOpen
Transactional First Proxy Open (unique_proxy_open)
The first proxy-based open recorded for the transactional message.
✉
TxClick
Transactional Click
The recipient clicked a tracked link in the transactional message.
✉
TxUnsubscribed
Transactional Unsubscribed
The recipient unsubscribed from the transactional message.
✉
MkOpened
Marketing Opened
A recipient opened a marketing campaign email.
✉
MkClick
Marketing Click
A recipient clicked a tracked link in a marketing campaign email.
✉
MkListAddition
Contact Added To List (list_addition)
A contact was added to one or more lists.
✉
MkContactUpdated
Contact Updated (contact_updated)
One or more attributes of a contact were updated.
✉
MkContactDeleted
Contact Deleted (contact_deleted)
A contact was deleted from the account.
Servers
https
subscriber{webhookUrl}
Customer-hosted HTTPS endpoint that receives webhook POSTs from Brevo. The full URL (including path) is configured per webhook in the Brevo dashboard or via the Webhooks API. A separate subscriber URL is configured per webhook record, and a single URL may be reused across multiple event types.
asyncapi: 2.6.0
info:
title: Brevo (Sendinblue) Webhooks
version: '1.0.0'
description: |-
AsyncAPI description of the outbound webhook surface for Brevo (formerly
Sendinblue). Brevo delivers event notifications by issuing HTTP POST
requests with a JSON body to a URL configured by the customer. There are
two distinct webhook product lines:
- Transactional webhooks: events for transactional email (and SMS)
sent through Brevo's SMTP/API relay.
- Marketing webhooks: events for marketing email campaigns and for
contact-list lifecycle activity.
Each event carries an `event` discriminator field whose value identifies
the event class (for example `request`, `delivered`, `hard_bounce`,
`click`, `unique_opened`, `list_addition`, `contact_updated`).
Source documentation:
- Transactional webhooks: https://developers.brevo.com/docs/transactional-webhooks
- Marketing webhooks: https://developers.brevo.com/docs/marketing-webhooks
- Webhooks overview: https://developers.brevo.com/docs/how-to-use-webhooks
Security:
Brevo does not document an HMAC signature header or a fixed signing
secret for outbound webhooks. The documented hardening options are
(1) embedding HTTP Basic credentials in the webhook URL and (2)
restricting the subscriber endpoint to Brevo's published source IP
ranges. Both options are modelled below in
`components.securitySchemes`.
contact:
name: Brevo Support
url: https://www.brevo.com/contact/
license:
name: Brevo Terms of Service
url: https://www.brevo.com/legal/termsofuse/
defaultContentType: application/json
servers:
subscriber:
url: '{webhookUrl}'
protocol: https
description: |-
Customer-hosted HTTPS endpoint that receives webhook POSTs from Brevo.
The full URL (including path) is configured per webhook in the Brevo
dashboard or via the Webhooks API. A separate subscriber URL is
configured per webhook record, and a single URL may be reused across
multiple event types.
variables:
webhookUrl:
default: https://example.com/brevo/webhook
description: Fully-qualified HTTPS URL of the subscriber endpoint.
security:
- basicAuth: []
- ipAllowList: []
channels:
/brevo/transactional/webhook:
description: |-
Subscriber endpoint that receives Brevo transactional email webhook
events. Brevo POSTs one event per HTTP request. The `event` field in
the JSON body identifies the event class.
bindings:
http:
type: request
method: POST
bindingVersion: '0.3.0'
publish:
operationId: receiveTransactionalWebhook
summary: Receive a Brevo transactional email webhook event
description: |-
Brevo POSTs a JSON event to the subscriber endpoint. Subscribers
should respond with a 2xx status code. Event ordering is not
guaranteed; consumers should rely on the `ts_event` / `ts_epoch`
timestamps and on `message-id` for correlation.
message:
oneOf:
- $ref: '#/components/messages/TxRequest'
- $ref: '#/components/messages/TxDelivered'
- $ref: '#/components/messages/TxSoftBounce'
- $ref: '#/components/messages/TxHardBounce'
- $ref: '#/components/messages/TxBlocked'
- $ref: '#/components/messages/TxInvalidEmail'
- $ref: '#/components/messages/TxDeferred'
- $ref: '#/components/messages/TxError'
- $ref: '#/components/messages/TxSpam'
- $ref: '#/components/messages/TxOpened'
- $ref: '#/components/messages/TxUniqueOpened'
- $ref: '#/components/messages/TxProxyOpen'
- $ref: '#/components/messages/TxUniqueProxyOpen'
- $ref: '#/components/messages/TxClick'
- $ref: '#/components/messages/TxUnsubscribed'
/brevo/marketing/webhook:
description: |-
Subscriber endpoint that receives Brevo marketing webhook events. Brevo
POSTs one event per HTTP request. The `event` field in the JSON body
identifies the event class. Marketing webhooks cover both campaign
activity (opens, clicks, bounces, unsubscribes) and contact-list
lifecycle activity (list additions, contact updates, contact deletes).
bindings:
http:
type: request
method: POST
bindingVersion: '0.3.0'
publish:
operationId: receiveMarketingWebhook
summary: Receive a Brevo marketing webhook event
description: |-
Brevo POSTs a JSON event to the subscriber endpoint. Subscribers
should respond with a 2xx status code. The `camp_id` field identifies
the originating campaign for campaign-driven events; contact
lifecycle events use a `key` field instead.
message:
oneOf:
- $ref: '#/components/messages/MkOpened'
- $ref: '#/components/messages/MkClick'
- $ref: '#/components/messages/MkListAddition'
- $ref: '#/components/messages/MkContactUpdated'
- $ref: '#/components/messages/MkContactDeleted'
components:
securitySchemes:
basicAuth:
type: httpApiKey
description: |-
HTTP Basic credentials embedded directly in the webhook URL
(for example `https://user:[email protected]/webhook`). Brevo sends
them in the standard `Authorization: Basic <base64>` header on each
POST.
name: Authorization
in: header
ipAllowList:
type: httpApiKey
description: |-
Source IP allowlist. Brevo documents the IP ranges used by its
webhook delivery workers; subscribers may restrict inbound POSTs to
those addresses. Modelled here as a transport-layer scheme because
AsyncAPI 2.6 has no first-class IP allowlist type.
name: X-Forwarded-For
in: header
messages:
# ---------- Transactional email messages ----------
TxRequest:
name: TxRequest
title: Transactional Sent (request)
summary: A transactional email was accepted by Brevo for sending.
contentType: application/json
payload:
$ref: '#/components/schemas/TxRequestPayload'
TxDelivered:
name: TxDelivered
title: Transactional Delivered
summary: A transactional email was accepted by the recipient mail server.
contentType: application/json
payload:
$ref: '#/components/schemas/TxDeliveredPayload'
TxSoftBounce:
name: TxSoftBounce
title: Transactional Soft Bounce
summary: A transactional email was temporarily rejected by the recipient mail server.
contentType: application/json
payload:
$ref: '#/components/schemas/TxSoftBouncePayload'
TxHardBounce:
name: TxHardBounce
title: Transactional Hard Bounce
summary: A transactional email was permanently rejected by the recipient mail server.
contentType: application/json
payload:
$ref: '#/components/schemas/TxHardBouncePayload'
TxBlocked:
name: TxBlocked
title: Transactional Blocked
summary: A transactional email was blocked before sending (for example, the recipient is on the account-level block list).
contentType: application/json
payload:
$ref: '#/components/schemas/TxBlockedPayload'
TxInvalidEmail:
name: TxInvalidEmail
title: Transactional Invalid Email
summary: The recipient address was rejected as syntactically invalid.
contentType: application/json
payload:
$ref: '#/components/schemas/TxInvalidEmailPayload'
TxDeferred:
name: TxDeferred
title: Transactional Deferred
summary: The recipient mail server temporarily deferred the message; Brevo will retry.
contentType: application/json
payload:
$ref: '#/components/schemas/TxDeferredPayload'
TxError:
name: TxError
title: Transactional Error
summary: A processing error occurred while handling the transactional message.
contentType: application/json
payload:
$ref: '#/components/schemas/TxErrorPayload'
TxSpam:
name: TxSpam
title: Transactional Spam Complaint
summary: The recipient flagged the transactional message as spam.
contentType: application/json
payload:
$ref: '#/components/schemas/TxSpamPayload'
TxOpened:
name: TxOpened
title: Transactional Opened
summary: The recipient opened the transactional message (may fire multiple times).
contentType: application/json
payload:
$ref: '#/components/schemas/TxOpenedPayload'
TxUniqueOpened:
name: TxUniqueOpened
title: Transactional First Open (unique_opened)
summary: The recipient opened the transactional message for the first time.
contentType: application/json
payload:
$ref: '#/components/schemas/TxUniqueOpenedPayload'
TxProxyOpen:
name: TxProxyOpen
title: Transactional Proxy Open
summary: The transactional message was opened via a mail-privacy proxy (for example Apple Mail Privacy Protection).
contentType: application/json
payload:
$ref: '#/components/schemas/TxProxyOpenPayload'
TxUniqueProxyOpen:
name: TxUniqueProxyOpen
title: Transactional First Proxy Open (unique_proxy_open)
summary: The first proxy-based open recorded for the transactional message.
contentType: application/json
payload:
$ref: '#/components/schemas/TxUniqueProxyOpenPayload'
TxClick:
name: TxClick
title: Transactional Click
summary: The recipient clicked a tracked link in the transactional message.
contentType: application/json
payload:
$ref: '#/components/schemas/TxClickPayload'
TxUnsubscribed:
name: TxUnsubscribed
title: Transactional Unsubscribed
summary: The recipient unsubscribed from the transactional message.
contentType: application/json
payload:
$ref: '#/components/schemas/TxUnsubscribedPayload'
# ---------- Marketing messages ----------
MkOpened:
name: MkOpened
title: Marketing Opened
summary: A recipient opened a marketing campaign email.
contentType: application/json
payload:
$ref: '#/components/schemas/MkOpenedPayload'
MkClick:
name: MkClick
title: Marketing Click
summary: A recipient clicked a tracked link in a marketing campaign email.
contentType: application/json
payload:
$ref: '#/components/schemas/MkClickPayload'
MkListAddition:
name: MkListAddition
title: Contact Added To List (list_addition)
summary: A contact was added to one or more lists.
contentType: application/json
payload:
$ref: '#/components/schemas/MkListAdditionPayload'
MkContactUpdated:
name: MkContactUpdated
title: Contact Updated (contact_updated)
summary: One or more attributes of a contact were updated.
contentType: application/json
payload:
$ref: '#/components/schemas/MkContactUpdatedPayload'
MkContactDeleted:
name: MkContactDeleted
title: Contact Deleted (contact_deleted)
summary: A contact was deleted from the account.
contentType: application/json
payload:
$ref: '#/components/schemas/MkContactDeletedPayload'
schemas:
# ---------- Shared base schema for transactional email events ----------
TxEmailBase:
type: object
description: |-
Fields common to all transactional email webhook events. The `event`
field is the discriminator. `ts_epoch` is documented as UTC
milliseconds for most events; `ts` and `ts_event` are seconds. `date`
is rendered in CET/CEST per Brevo's documentation.
required:
- event
- email
- id
- message-id
properties:
event:
type: string
description: Event discriminator (for example `request`, `delivered`, `click`).
email:
type: string
format: email
description: Recipient email address.
id:
type: integer
description: Brevo internal numeric identifier for the event row.
date:
type: string
description: Event date and time in CET/CEST, formatted `YYYY-MM-DD HH:MM:SS`.
example: '2020-10-09 00:00:00'
ts:
type: integer
description: UTC timestamp in seconds.
example: 1604933619
message-id:
type: string
description: SMTP message identifier for the sent transactional message.
example: [email protected]
ts_event:
type: integer
description: UTC timestamp of the event itself, in seconds.
example: 1604933654
subject:
type: string
description: Subject line of the originating transactional email.
X-Mailin-custom:
type: string
description: Free-form custom header value passed by the sender at submission time.
sending_ip:
type: string
description: IP address from which the email was sent.
ts_epoch:
type: integer
format: int64
description: UTC timestamp in milliseconds. Documented for most transactional events.
example: 1604933654000
template_id:
type: integer
description: Identifier of the Brevo template used for the message, if any.
tags:
type: array
description: Tag values supplied by the sender at submission time.
items:
type: string
tag:
type: string
description: |-
JSON-encoded tag value used on some events (notably `unsubscribed`,
`proxy_open`, and `unique_proxy_open`).
mirror_link:
type: string
format: uri
description: Brevo log preview URL for the message.
contact_id:
type: integer
format: int64
description: Brevo contact identifier for the recipient. Zero when no contact exists.
TxRequestPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [request]
TxDeliveredPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [delivered]
TxSoftBouncePayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [soft_bounce]
reason:
type: string
description: Human-readable explanation supplied by the remote mail server.
TxHardBouncePayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [hard_bounce]
reason:
type: string
description: Human-readable explanation supplied by the remote mail server.
TxBlockedPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [blocked]
TxInvalidEmailPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [invalid_email]
TxDeferredPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [deferred]
reason:
type: string
description: Reason supplied by the remote mail server for the deferral.
TxErrorPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [error]
TxSpamPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [spam]
TxOpenedPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [opened]
user_agent:
type: string
description: User-Agent header reported by the opener's mail client.
device_used:
type: string
description: Device class inferred from the User-Agent.
example: DESKTOP
TxUniqueOpenedPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [unique_opened]
user_agent:
type: string
device_used:
type: string
TxProxyOpenPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [proxy_open]
user_agent:
type: string
device_used:
type: string
TxUniqueProxyOpenPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [unique_proxy_open]
link:
type: string
description: Empty string on proxy opens; preserved by Brevo for shape parity with click events.
sender_email:
type: string
format: email
description: Originating sender address for the message.
user_agent:
type: string
device_used:
type: string
TxClickPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [click]
link:
type: string
format: uri
description: URL that was clicked.
user_agent:
type: string
device_used:
type: string
TxUnsubscribedPayload:
allOf:
- $ref: '#/components/schemas/TxEmailBase'
- type: object
properties:
event:
type: string
enum: [unsubscribed]
user_agent:
type: string
device_used:
type: string
# ---------- Marketing event schemas ----------
MkCampaignBase:
type: object
description: |-
Fields common to marketing campaign events (opened, click). Brevo
documents `ts_sent` and `ts_event` in seconds, and `ts` as the
webhook delivery timestamp in seconds.
required:
- event
- email
- camp_id
properties:
id:
type: integer
description: Webhook delivery identifier.
camp_id:
type: integer
description: Identifier of the originating marketing campaign.
email:
type: string
format: email
campaign name:
type: string
description: Campaign name. Note the literal space in the field key as documented by Brevo.
date_sent:
type: string
description: Send time, formatted `YYYY-MM-DD HH:MM:SS`.
date_event:
type: string
description: Event time, formatted `YYYY-MM-DD HH:MM:SS`.
event:
type: string
description: Event discriminator.
tag:
type: string
description: Campaign tag (may be empty).
segment_ids:
type: array
description: Identifiers of the segments the recipient belonged to at send time.
items:
type: integer
ts_sent:
type: integer
description: UTC send timestamp in seconds.
ts_event:
type: integer
description: UTC event timestamp in seconds.
ts:
type: integer
description: UTC webhook delivery timestamp in seconds.
MkOpenedPayload:
allOf:
- $ref: '#/components/schemas/MkCampaignBase'
- type: object
properties:
event:
type: string
enum: [opened]
MkClickPayload:
allOf:
- $ref: '#/components/schemas/MkCampaignBase'
- type: object
required:
- URL
properties:
event:
type: string
enum: [click]
URL:
type: string
format: uri
description: URL that was clicked. Uppercase per Brevo's documented payload.
MkListAdditionPayload:
type: object
description: Contact was added to one or more Brevo contact lists.
required:
- event
- email
properties:
id:
type: string
description: Webhook delivery identifier (string per documented example).
email:
type: string
format: email
event:
type: string
enum: [list_addition]
key:
type: string
description: Account-level webhook key supplied by Brevo.
list_id:
type: array
description: Identifiers of the lists the contact was added to.
items:
type: integer
date:
type: string
description: Event date and time, formatted `YYYY-MM-DD HH:MM:SS`.
ts:
type: integer
description: UTC timestamp in seconds.
MkContactUpdatedPayload:
type: object
description: Attributes of a contact were updated.
required:
- event
- email
properties:
id:
type: integer
email:
type: string
format: email
event:
type: string
enum: [contact_updated]
key:
type: string
content:
type: array
description: |-
Array of attribute objects reflecting the updated contact state.
Brevo documents this as a list of free-form attribute objects.
items:
type: object
additionalProperties: true
date:
type: string
ts:
type: integer
MkContactDeletedPayload:
type: object
description: A contact was deleted.
required:
- event
- email
properties:
id:
type: integer
email:
type: string
format: email
event:
type: string
enum: [contact_deleted]
key:
type: string
list_id:
type: array
items:
type: integer
description: Identifiers of the lists the contact had been a member of.
date:
type: string
ts:
type: integer