Event catalog for the Loops webhook surface, derived operation-for-operation from the `webhooks` block of the Loops OpenAPI 3.1 document (info.version 1.21.6, published at https://app.loops.so/openapi.json). Loops does not publish an AsyncAPI document; it publishes these events inside its OpenAPI, and this file is a faithful projection of that block into AsyncAPI 3.0.0 so the event surface is readable by event tooling. Every channel, message name, summary and payload schema below comes verbatim from the provider. Delivery is a single HTTP POST to one subscriber-configured endpoint per Loops account, signed with HMAC-SHA256 over `{webhook-id}.{webhook-timestamp}.{raw-body}` and capped at 10 events per second.
View SpecView on GitHubEmailEmail APIMarketing AutomationTransactional EmailLifecycle EmailWebhookSoftware-as-a-ServiceCommunicationsDeveloper ToolsMCPAgentsCampaignsAsyncAPIWebhooksEvents
Channels
contactUnsubscribed
Delivered by HTTP POST to the account webhook endpoint.
contactCreated
Delivered by HTTP POST to the account webhook endpoint.
contactDeleted
Delivered by HTTP POST to the account webhook endpoint.
contactMailingListSubscribed
Delivered by HTTP POST to the account webhook endpoint.
contactMailingListUnsubscribed
Delivered by HTTP POST to the account webhook endpoint.
transactionalEmailSent
Delivered by HTTP POST to the account webhook endpoint.
campaignEmailSent
Delivered by HTTP POST to the account webhook endpoint.
loopEmailSent
Delivered by HTTP POST to the account webhook endpoint.
emailDelivered
Delivered by HTTP POST to the account webhook endpoint.
emailSoftBounced
Delivered by HTTP POST to the account webhook endpoint.
emailHardBounced
Delivered by HTTP POST to the account webhook endpoint.
emailClicked
Delivered by HTTP POST to the account webhook endpoint.
emailUnsubscribed
Delivered by HTTP POST to the account webhook endpoint.
emailResubscribed
Delivered by HTTP POST to the account webhook endpoint.
emailOpened
Delivered by HTTP POST to the account webhook endpoint.
emailSpamReported
Delivered by HTTP POST to the account webhook endpoint.
testingTestEvent
Delivered by HTTP POST to the account webhook endpoint.
Messages
✉
contactUnsubscribed
Contact unsubscribed
Sent when a contact is unsubscribed from your audience, or when a contact is deleted from your audience (alongside `contact.deleted`). This is not the same as a contact unsubscribing from a mailing list (see `contact.mailingList.unsubscribed`). Contains a `contactIdentity` object.
✉
contactCreated
Contact created
Sent when a new contact is created in your audience. Contains a `contactIdentity` object and a full `contact` object with all of the new contact's properties (including custom properties). When double opt-in is enabled, contact webhooks do not fire until the contact is confirmed; `contact.created` only fires for form-created contacts once they confirm their subscription. `optInStatus` will never be `"pending"` or `"rejected"` for this event.
✉
contactDeleted
Contact deleted
Sent when a contact is deleted from your audience. Contains a `contactIdentity` object.
✉
contactMailingListSubscribed
Contact subscribed to mailing list
Sent when a contact is subscribed to a mailing list. Contains `contactIdentity` and `mailingList` objects. When double opt-in is enabled, this event only fires after the contact confirms their subscription.
✉
contactMailingListUnsubscribed
Contact unsubscribed from mailing list
Sent when a contact is unsubscribed from a mailing list. This is not the same as a contact unsubscribing from your audience (see `contact.unsubscribed`). Contains `contactIdentity` and `mailingList` objects.
✉
transactionalEmailSent
Transactional email sent
Sent when a transactional email is sent to a contact. Contains a `transactionalId` value plus `contactIdentity` and `email` objects.
✉
campaignEmailSent
Campaign email sent
Sent when a campaign email is sent to a contact. This event fires for every campaign send (for example, sending to 1,000 contacts produces 1,000 events). Contains `campaignId` and `campaignName` plus `contactIdentity` and `email` objects. If the campaign was sent to one or more mailing lists, a `mailingLists` array is also included.
✉
loopEmailSent
Loop email sent
Sent when a workflow email is sent to a contact. This event keeps its `loop` naming for compatibility (Loops was renamed to Workflows on May 6, 2026). This event fires for every contact in a workflow (for example, 1,000 recipients produces 1,000 events). Contains `loopId` and `loopName` plus `contactIdentity` and `email` objects. If the workflow was sent to one or more mailing lists, a `mailingLists` array is also included.
✉
emailDelivered
Email delivered
Sent when an email is delivered to its recipient. Contains `sourceType` (`campaign`, `loop`, or `transactional`) and the related `campaignId`, `loopId` (workflow ID), or `transactionalId`, plus `contactIdentity` and `email` objects.
✉
emailSoftBounced
Email soft bounced
Sent when an email soft bounces. Soft bounces are temporary delivery failures (for example, a connection timing out). Soft bounces are retried multiple times and the email may still be delivered. Contains `sourceType` and the related `campaignId`, `loopId` (workflow ID), or `transactionalId`, plus `contactIdentity` and `email` objects.
✉
emailHardBounced
Email hard bounced
Sent when an email hard bounces. Hard bounces are persistent delivery failures (for example, a mailbox that does not exist); the email will not be delivered. In Loops, a hard bounce also unsubscribes the contact from your audience, so a `contact.unsubscribed` event will also be sent. Contains `sourceType` and the related `campaignId`, `loopId` (workflow ID), or `transactionalId`, plus `contactIdentity` and `email` objects.
✉
emailClicked
Email clicked
Sent when a link in a campaign or workflow email is clicked. Not available for transactional emails because link clicks are not tracked for transactional emails. Contains `sourceType` and the related `campaignId` or `loopId` (workflow ID), plus `contactIdentity` and `email` objects.
✉
emailUnsubscribed
Email unsubscribed
Sent when a recipient unsubscribes from marketing email or a mailing list using an email's "Unsubscribe" link. A `contact.unsubscribed` or `contact.mailingList.unsubscribed` event will also be sent depending on whether the email was sent to a mailing list. Not available for transactional emails because unsubscribe links are not included for transactional emails. Contains `sourceType` and the related `campaignId` or `loopId` (workflow ID), plus `contactIdentity` and `email` objects.
✉
emailResubscribed
Email resubscribed
Sent when a recipient resubscribes to marketing email from an email's preference center ("Unsubscribe" link). Not available for transactional emails because unsubscribe links are not included for transactional emails. Contains `sourceType` and the related `campaignId` or `loopId` (workflow ID), plus `contactIdentity` and `email` objects.
✉
emailOpened
Email opened
Sent when a campaign or workflow email is opened. Not available for transactional emails because email opens are not tracked for transactional emails. Contains `sourceType` and the related `campaignId` or `loopId` (workflow ID), plus `contactIdentity` and `email` objects.
✉
emailSpamReported
Email spam reported
Sent when a recipient reports your email as spam. Contains `sourceType` and the related `campaignId`, `loopId` (workflow ID), or `transactionalId`, plus `contactIdentity` and `email` objects.
✉
testingTestEvent
Test event
Test event that can be triggered from the Webhooks settings page in Loops. Use this to verify that your endpoint is working and that your signature verification code is correct. The payload contains `eventName`, `eventTime`, `message` (always `"test"`), and `webhookSchemaVersion`.
Servers
https
subscriber
The single endpoint URL configured by the Loops account holder at https://app.loops.so/settings?page=webhooks. Loops permits one webhook endpoint per account.
# generated: '2026-08-13'
# method: derived
# source: openapi/_original/loops-openapi.yaml (webhooks block, info.version 1.21.6) + https://loops.so/docs/webhooks
asyncapi: 3.0.0
info:
title: Loops Webhooks
version: 1.21.6
description: Event catalog for the Loops webhook surface, derived operation-for-operation from the `webhooks` block of the Loops OpenAPI 3.1 document (info.version 1.21.6, published at https://app.loops.so/openapi.json). Loops does not publish an AsyncAPI document; it publishes these events inside its OpenAPI, and this file is a faithful projection of that block into AsyncAPI 3.0.0 so the event surface is readable by event tooling. Every channel, message name, summary and payload schema below comes verbatim from the provider. Delivery is a single HTTP POST to one subscriber-configured endpoint per Loops account, signed with HMAC-SHA256 over `{webhook-id}.{webhook-timestamp}.{raw-body}` and capped at 10 events per second.
externalDocs:
description: Loops webhooks documentation
url: https://loops.so/docs/webhooks
defaultContentType: application/json
servers:
subscriber:
host: '{subscriberEndpoint}'
protocol: https
description: The single endpoint URL configured by the Loops account holder at https://app.loops.so/settings?page=webhooks. Loops permits one webhook endpoint per account.
variables:
subscriberEndpoint:
description: Your HTTPS endpoint that receives Loops events.
default: example.com/webhooks/loops
channels:
contactUnsubscribed:
address: /
title: Contact unsubscribed
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
contactUnsubscribed:
$ref: '#/components/messages/contactUnsubscribed'
contactCreated:
address: /
title: Contact created
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
contactCreated:
$ref: '#/components/messages/contactCreated'
contactDeleted:
address: /
title: Contact deleted
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
contactDeleted:
$ref: '#/components/messages/contactDeleted'
contactMailingListSubscribed:
address: /
title: Contact subscribed to mailing list
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
contactMailingListSubscribed:
$ref: '#/components/messages/contactMailingListSubscribed'
contactMailingListUnsubscribed:
address: /
title: Contact unsubscribed from mailing list
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
contactMailingListUnsubscribed:
$ref: '#/components/messages/contactMailingListUnsubscribed'
transactionalEmailSent:
address: /
title: Transactional email sent
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
transactionalEmailSent:
$ref: '#/components/messages/transactionalEmailSent'
campaignEmailSent:
address: /
title: Campaign email sent
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
campaignEmailSent:
$ref: '#/components/messages/campaignEmailSent'
loopEmailSent:
address: /
title: Loop email sent
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
loopEmailSent:
$ref: '#/components/messages/loopEmailSent'
emailDelivered:
address: /
title: Email delivered
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
emailDelivered:
$ref: '#/components/messages/emailDelivered'
emailSoftBounced:
address: /
title: Email soft bounced
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
emailSoftBounced:
$ref: '#/components/messages/emailSoftBounced'
emailHardBounced:
address: /
title: Email hard bounced
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
emailHardBounced:
$ref: '#/components/messages/emailHardBounced'
emailClicked:
address: /
title: Email clicked
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
emailClicked:
$ref: '#/components/messages/emailClicked'
emailUnsubscribed:
address: /
title: Email unsubscribed
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
emailUnsubscribed:
$ref: '#/components/messages/emailUnsubscribed'
emailResubscribed:
address: /
title: Email resubscribed
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
emailResubscribed:
$ref: '#/components/messages/emailResubscribed'
emailOpened:
address: /
title: Email opened
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
emailOpened:
$ref: '#/components/messages/emailOpened'
emailSpamReported:
address: /
title: Email spam reported
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
emailSpamReported:
$ref: '#/components/messages/emailSpamReported'
testingTestEvent:
address: /
title: Test event
description: Delivered by HTTP POST to the account webhook endpoint.
servers:
- $ref: '#/servers/subscriber'
messages:
testingTestEvent:
$ref: '#/components/messages/testingTestEvent'
operations:
receive_contactUnsubscribed:
action: receive
channel:
$ref: '#/channels/contactUnsubscribed'
summary: Contact unsubscribed
messages:
- $ref: '#/channels/contactUnsubscribed/messages/contactUnsubscribed'
receive_contactCreated:
action: receive
channel:
$ref: '#/channels/contactCreated'
summary: Contact created
messages:
- $ref: '#/channels/contactCreated/messages/contactCreated'
receive_contactDeleted:
action: receive
channel:
$ref: '#/channels/contactDeleted'
summary: Contact deleted
messages:
- $ref: '#/channels/contactDeleted/messages/contactDeleted'
receive_contactMailingListSubscribed:
action: receive
channel:
$ref: '#/channels/contactMailingListSubscribed'
summary: Contact subscribed to mailing list
messages:
- $ref: '#/channels/contactMailingListSubscribed/messages/contactMailingListSubscribed'
receive_contactMailingListUnsubscribed:
action: receive
channel:
$ref: '#/channels/contactMailingListUnsubscribed'
summary: Contact unsubscribed from mailing list
messages:
- $ref: '#/channels/contactMailingListUnsubscribed/messages/contactMailingListUnsubscribed'
receive_transactionalEmailSent:
action: receive
channel:
$ref: '#/channels/transactionalEmailSent'
summary: Transactional email sent
messages:
- $ref: '#/channels/transactionalEmailSent/messages/transactionalEmailSent'
receive_campaignEmailSent:
action: receive
channel:
$ref: '#/channels/campaignEmailSent'
summary: Campaign email sent
messages:
- $ref: '#/channels/campaignEmailSent/messages/campaignEmailSent'
receive_loopEmailSent:
action: receive
channel:
$ref: '#/channels/loopEmailSent'
summary: Loop email sent
messages:
- $ref: '#/channels/loopEmailSent/messages/loopEmailSent'
receive_emailDelivered:
action: receive
channel:
$ref: '#/channels/emailDelivered'
summary: Email delivered
messages:
- $ref: '#/channels/emailDelivered/messages/emailDelivered'
receive_emailSoftBounced:
action: receive
channel:
$ref: '#/channels/emailSoftBounced'
summary: Email soft bounced
messages:
- $ref: '#/channels/emailSoftBounced/messages/emailSoftBounced'
receive_emailHardBounced:
action: receive
channel:
$ref: '#/channels/emailHardBounced'
summary: Email hard bounced
messages:
- $ref: '#/channels/emailHardBounced/messages/emailHardBounced'
receive_emailClicked:
action: receive
channel:
$ref: '#/channels/emailClicked'
summary: Email clicked
messages:
- $ref: '#/channels/emailClicked/messages/emailClicked'
receive_emailUnsubscribed:
action: receive
channel:
$ref: '#/channels/emailUnsubscribed'
summary: Email unsubscribed
messages:
- $ref: '#/channels/emailUnsubscribed/messages/emailUnsubscribed'
receive_emailResubscribed:
action: receive
channel:
$ref: '#/channels/emailResubscribed'
summary: Email resubscribed
messages:
- $ref: '#/channels/emailResubscribed/messages/emailResubscribed'
receive_emailOpened:
action: receive
channel:
$ref: '#/channels/emailOpened'
summary: Email opened
messages:
- $ref: '#/channels/emailOpened/messages/emailOpened'
receive_emailSpamReported:
action: receive
channel:
$ref: '#/channels/emailSpamReported'
summary: Email spam reported
messages:
- $ref: '#/channels/emailSpamReported/messages/emailSpamReported'
receive_testingTestEvent:
action: receive
channel:
$ref: '#/channels/testingTestEvent'
summary: Test event
messages:
- $ref: '#/channels/testingTestEvent/messages/testingTestEvent'
components:
messages:
contactUnsubscribed:
name: contactUnsubscribed
title: Contact unsubscribed
summary: Sent when a contact is unsubscribed from your audience, or when a contact is deleted from your audience (alongside `contact.deleted`). This is not the same as a contact unsubscribing from a mailing list (see `contact.mailingList.unsubscribed`). Contains a `contactIdentity` object.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookContactUnsubscribedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
contactCreated:
name: contactCreated
title: Contact created
summary: Sent when a new contact is created in your audience. Contains a `contactIdentity` object and a full `contact` object with all of the new contact's properties (including custom properties). When double opt-in is enabled, contact webhooks do not fire until the contact is confirmed; `contact.created` only fires for form-created contacts once they confirm their subscription. `optInStatus` will never be `"pending"` or `"rejected"` for this event.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookContactCreatedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
contactDeleted:
name: contactDeleted
title: Contact deleted
summary: Sent when a contact is deleted from your audience. Contains a `contactIdentity` object.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookContactDeletedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
contactMailingListSubscribed:
name: contactMailingListSubscribed
title: Contact subscribed to mailing list
summary: Sent when a contact is subscribed to a mailing list. Contains `contactIdentity` and `mailingList` objects. When double opt-in is enabled, this event only fires after the contact confirms their subscription.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookContactMailingListSubscribedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
contactMailingListUnsubscribed:
name: contactMailingListUnsubscribed
title: Contact unsubscribed from mailing list
summary: Sent when a contact is unsubscribed from a mailing list. This is not the same as a contact unsubscribing from your audience (see `contact.unsubscribed`). Contains `contactIdentity` and `mailingList` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookContactMailingListUnsubscribedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
transactionalEmailSent:
name: transactionalEmailSent
title: Transactional email sent
summary: Sent when a transactional email is sent to a contact. Contains a `transactionalId` value plus `contactIdentity` and `email` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookTransactionalEmailSentPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
campaignEmailSent:
name: campaignEmailSent
title: Campaign email sent
summary: Sent when a campaign email is sent to a contact. This event fires for every campaign send (for example, sending to 1,000 contacts produces 1,000 events). Contains `campaignId` and `campaignName` plus `contactIdentity` and `email` objects. If the campaign was sent to one or more mailing lists, a `mailingLists` array is also included.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookCampaignEmailSentPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
loopEmailSent:
name: loopEmailSent
title: Loop email sent
summary: Sent when a workflow email is sent to a contact. This event keeps its `loop` naming for compatibility (Loops was renamed to Workflows on May 6, 2026). This event fires for every contact in a workflow (for example, 1,000 recipients produces 1,000 events). Contains `loopId` and `loopName` plus `contactIdentity` and `email` objects. If the workflow was sent to one or more mailing lists, a `mailingLists` array is also included.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookLoopEmailSentPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
emailDelivered:
name: emailDelivered
title: Email delivered
summary: Sent when an email is delivered to its recipient. Contains `sourceType` (`campaign`, `loop`, or `transactional`) and the related `campaignId`, `loopId` (workflow ID), or `transactionalId`, plus `contactIdentity` and `email` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookEmailDeliveredPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
emailSoftBounced:
name: emailSoftBounced
title: Email soft bounced
summary: Sent when an email soft bounces. Soft bounces are temporary delivery failures (for example, a connection timing out). Soft bounces are retried multiple times and the email may still be delivered. Contains `sourceType` and the related `campaignId`, `loopId` (workflow ID), or `transactionalId`, plus `contactIdentity` and `email` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookEmailSoftBouncedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
emailHardBounced:
name: emailHardBounced
title: Email hard bounced
summary: Sent when an email hard bounces. Hard bounces are persistent delivery failures (for example, a mailbox that does not exist); the email will not be delivered. In Loops, a hard bounce also unsubscribes the contact from your audience, so a `contact.unsubscribed` event will also be sent. Contains `sourceType` and the related `campaignId`, `loopId` (workflow ID), or `transactionalId`, plus `contactIdentity` and `email` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookEmailHardBouncedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
emailClicked:
name: emailClicked
title: Email clicked
summary: Sent when a link in a campaign or workflow email is clicked. Not available for transactional emails because link clicks are not tracked for transactional emails. Contains `sourceType` and the related `campaignId` or `loopId` (workflow ID), plus `contactIdentity` and `email` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookEmailClickedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
emailUnsubscribed:
name: emailUnsubscribed
title: Email unsubscribed
summary: Sent when a recipient unsubscribes from marketing email or a mailing list using an email's "Unsubscribe" link. A `contact.unsubscribed` or `contact.mailingList.unsubscribed` event will also be sent depending on whether the email was sent to a mailing list. Not available for transactional emails because unsubscribe links are not included for transactional emails. Contains `sourceType` and the related `campaignId` or `loopId` (workflow ID), plus `contactIdentity` and `email` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookEmailUnsubscribedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
emailResubscribed:
name: emailResubscribed
title: Email resubscribed
summary: Sent when a recipient resubscribes to marketing email from an email's preference center ("Unsubscribe" link). Not available for transactional emails because unsubscribe links are not included for transactional emails. Contains `sourceType` and the related `campaignId` or `loopId` (workflow ID), plus `contactIdentity` and `email` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookEmailResubscribedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
emailOpened:
name: emailOpened
title: Email opened
summary: Sent when a campaign or workflow email is opened. Not available for transactional emails because email opens are not tracked for transactional emails. Contains `sourceType` and the related `campaignId` or `loopId` (workflow ID), plus `contactIdentity` and `email` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookEmailOpenedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
emailSpamReported:
name: emailSpamReported
title: Email spam reported
summary: Sent when a recipient reports your email as spam. Contains `sourceType` and the related `campaignId`, `loopId` (workflow ID), or `transactionalId`, plus `contactIdentity` and `email` objects.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookEmailSpamReportedPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
testingTestEvent:
name: testingTestEvent
title: Test event
summary: Test event that can be triggered from the Webhooks settings page in Loops. Use this to verify that your endpoint is working and that your signature verification code is correct. The payload contains `eventName`, `eventTime`, `message` (always `"test"`), and `webhookSchemaVersion`.
contentType: application/json
payload:
$ref: '#/components/schemas/WebhookTestingTestEventPayload'
headers:
$ref: '#/components/schemas/LoopsWebhookHeaders'
schemas:
WebhookBasePayload:
type: object
required:
- eventName
- eventTime
- webhookSchemaVersion
- contactIdentity
properties:
eventName:
type: string
eventTime:
type: integer
description: Unix timestamp in seconds.
webhookSchemaVersion:
type: string
const: 1.0.0
contactIdentity:
$ref: '#/components/schemas/WebhookContactIdentity'
WebhookCampaignEmailSentPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- eventName
- campaignId
- email
- mailingLists
- campaignName
properties:
eventName:
type: string
const: campaign.email.sent
campaignId:
type: string
campaignName:
type: string
email:
$ref: '#/components/schemas/WebhookEmail'
mailingLists:
type: array
description: The mailing list(s) the email was sent to, or an empty array.
items:
$ref: '#/components/schemas/WebhookMailingList'
WebhookContact:
type: object
required:
- id
- email
- firstName
- lastName
- source
- subscribed
- userGroup
- userId
- mailingLists
- optInStatus
properties:
id:
type: string
email:
type: string
firstName:
type:
- string
- 'null'
lastName:
type:
- string
- 'null'
source:
type: string
subscribed:
type: boolean
userGroup:
type: string
userId:
type:
- string
- 'null'
notes:
type:
- string
- 'null'
mailingLists:
type: object
description: An object of mailing list IDs and boolean subscription statuses.
additionalProperties:
type: boolean
optInStatus:
type:
- string
- 'null'
description: Double opt-in status.
enum:
- accepted
- pending
- rejected
- null
additionalProperties: true
description: Full contact object, including custom properties.
WebhookContactCreatedPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- eventName
- contact
properties:
eventName:
type: string
const: contact.created
contact:
$ref: '#/components/schemas/WebhookContact'
WebhookContactDeletedPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: contact.deleted
WebhookContactIdentity:
type: object
required:
- id
- email
- userId
properties:
id:
type: string
email:
type: string
userId:
type:
- string
- 'null'
WebhookContactMailingListSubscribedPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- eventName
- mailingList
properties:
eventName:
type: string
const: contact.mailingList.subscribed
mailingList:
$ref: '#/components/schemas/WebhookMailingList'
WebhookContactMailingListUnsubscribedPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- eventName
- mailingList
properties:
eventName:
type: string
const: contact.mailingList.unsubscribed
mailingList:
$ref: '#/components/schemas/WebhookMailingList'
WebhookContactUnsubscribedPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: contact.unsubscribed
WebhookEmail:
type: object
required:
- id
- emailMessageId
- subject
properties:
id:
type: string
description: The ID of the email.
emailMessageId:
type: string
description: The ID of the sent version of the campaign, workflow or transactional email.
subject:
type: string
description: The subject of the email.
WebhookEmailClickedPayload:
allOf:
- $ref: '#/components/schemas/WebhookMarketingEmailMetricPayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: email.clicked
WebhookEmailDeliveredPayload:
allOf:
- $ref: '#/components/schemas/WebhookEmailMetricPayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: email.delivered
WebhookEmailHardBouncedPayload:
allOf:
- $ref: '#/components/schemas/WebhookEmailMetricPayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: email.hardBounced
WebhookEmailMetricPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- email
- sourceType
properties:
email:
$ref: '#/components/schemas/WebhookEmail'
sourceType:
type: string
enum:
- loop
- campaign
- transactional
description: The type of email this event relates to. Workflow emails use `loop`.
campaignId:
type: string
description: The ID of the campaign if `sourceType` is `campaign`.
loopId:
type: string
description: The ID of the workflow if `sourceType` is `loop`.
transactionalId:
type: string
description: The ID of the transactional email if `sourceType` is `transactional`.
WebhookEmailOpenedPayload:
allOf:
- $ref: '#/components/schemas/WebhookMarketingEmailMetricPayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: email.opened
WebhookEmailResubscribedPayload:
allOf:
- $ref: '#/components/schemas/WebhookMarketingEmailMetricPayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: email.resubscribed
WebhookEmailSoftBouncedPayload:
allOf:
- $ref: '#/components/schemas/WebhookEmailMetricPayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: email.softBounced
WebhookEmailSpamReportedPayload:
allOf:
- $ref: '#/components/schemas/WebhookEmailMetricPayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: email.spamReported
WebhookEmailUnsubscribedPayload:
allOf:
- $ref: '#/components/schemas/WebhookMarketingEmailMetricPayload'
- type: object
required:
- eventName
properties:
eventName:
type: string
const: email.unsubscribed
WebhookLoopEmailSentPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- eventName
- loopId
- email
- mailingLists
- loopName
properties:
eventName:
type: string
const: loop.email.sent
loopId:
type: string
description: The ID of the workflow.
loopName:
type: string
description: The name of the workflow.
email:
$ref: '#/components/schemas/WebhookEmail'
mailingLists:
type: array
description: The mailing list(s) the email was sent to, or an empty array.
items:
$ref: '#/components/schemas/WebhookMailingList'
WebhookMailingList:
type: object
description: Details of the mailing list.
required:
- id
- name
- description
- isPublic
properties:
id:
type: string
name:
type: string
description:
type:
- string
- 'null'
isPublic:
type: boolean
WebhookMarketingEmailMetricPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- email
- sourceType
properties:
email:
$ref: '#/components/schemas/WebhookEmail'
sourceType:
type: string
enum:
- loop
- campaign
description: The type of email this event relates to. Workflow emails use `loop`. Not available for transactional emails.
campaignId:
type: string
description: The ID of the campaign if `sourceType` is `campaign`.
loopId:
type: string
description: The ID of the workflow if `sourceType` is `loop`.
WebhookTestingTestEventPayload:
type: object
required:
- eventName
- eventTime
- message
- webhookSchemaVersion
properties:
eventName:
type: string
const: testing.testEvent
eventTime:
type: integer
description: Unix timestamp in seconds.
message:
type: string
const: test
webhookSchemaVersion:
type: string
const: 1.0.0
WebhookTransactionalEmailSentPayload:
allOf:
- $ref: '#/components/schemas/WebhookBasePayload'
- type: object
required:
- eventName
- transactionalId
- email
- transactionalName
properties:
eventName:
type: string
const: transactional.email.sent
transactionalId:
type: string
transactionalName:
type: string
email:
$ref: '#/components/schemas/WebhookEmail'
LoopsWebhookHeaders:
type: object
description: Signature headers Loops sends with every webhook request. Verify by HMAC-SHA256 over `{webhook-id}.{webhook-timestamp}.{raw-body}` using the base64-decoded portion of the signing secret after the underscore.
properties:
webhook-id:
type: string
description: Unique event id.
webhook-timestamp:
type: string
description: Unix timestamp of the send.
webhook-signature:
type: string
description: Space-separated list of versioned base64 signatures.
required:
- webhook-id
- webhook-timestamp
- webhook-signature