Webhooks send data to your website or application when certain events happen in your Loops account.Documentation Index
Fetch the complete documentation index at: https://loops.so/docs/llms.txt
Use this file to discover all available pages before exploring further.
Set up webhooks
Go to Settings -> Webhooks and input the URL of your endpoint that will receive events. You will be provided with a signing secret. You should save this in your project (for example in an environment variable) so you can verify requests when you receive them. Currently you can only set up one webhook endpoint per Loops account. Subscribe to the events you want to receive using the toggles. Click the group names to view all events in each.
Rate limiting
Webhook events will be sent at a maximum rate of 10 per second. Any further events will be queued.Verify requests
Every event is signed so you can check that data sent to your endpoint is sent from Loops. To verify webhooks, you need to create a signature of the received request and match that to the provided signature in the request’s headers. Here’s an example verification function you could use in Next.js:Testing webhooks
From the Webhooks settings page you can send a test request to your endpoint. This allows you to test that your endpoint is working, and that your verification code is OK. The event name sent during testing istesting.testEvent. You can see the payload below.
Viewing webhook history
Once Loops has started sending webhook events to your endpoint you will be able to see event history in the Messages section at the bottom of the Webhooks settings page. Clicking on an event in the table will reveal the response from your endpoint, which is helpful if there have been any errors. We retain 30 days of event history.
Event data
Every webhook will contain the following data in the request body:Loops were renamed to Workflows on May 6, 2026. Webhook payloads still use
loop names for compatibility, including loop.email.sent, loopId,
loopName, and sourceType: "loop".eventName
The event type. See a full list of events below.
webhookSchemaVersion
Will be 1.0.0 for all events.
eventTime
Unix timestamp of the time the event occurred in Loops.
Depending on the context of the event, more data will also be included. Full examples are shown in the Event types section below.
contact
A full contact object containing a contact’s properties.
Contains:
idemailfirstName(nullable string)lastName(nullable string)sourcesubscribed(boolean)userGroupuserId(nullable string)mailingLists(object with mailing list IDs as keys andtrueas the value; these are the mailing lists the contact is subscribed to)optInStatus(nullable string,"accepted"ornull)This will benullfor contacts unless they are created via a form and double opt-in is enabled.contact.createdevents are only sent once contacts have confirmed their subscription, so this value will never be"pending"or"rejected".- plus any custom contact properties
contactIdentity
A contact’s identifiers. To retrieve the full contact, use the Find a contact API endpoint.
Contains:
idemailuserId(nullable string)
email
Details about an individual email send to a recipient:
id- The unique ID of the email.emailMessageId- The ID of the sent version of the campaign, workflow or transactional email.subject- The subject of the sent version of the campaign, workflow or transactional email.
To get the ID of the campaign, workflow or transactional email that relates to the
Loops dashboard or API, look for a
campaignId, loopId, or
transactionalId in the payload.mailingList
Details about a mailing list:
idnamedescription(nullable string)isPublic(boolean)
mailingLists
A list of mailingList objects (see above), when an event relates to multiple mailing lists.
sourceType
For email.* events, this specifies the type of email.
One of campaign, loop or transactional. Workflow emails use loop.
Headers
Headers will include:Webhook-Signature- A list of request signatures, which can be used to verify the request.Webhook-Id- The unique ID of the event. You can use this to check if you have already saved or processed this specific event.Webhook-Timestamp- The timestamp of the request (seconds since epoch).
Event types
Contacts
contact.created
Sent when a new contact is created in your audience. Contains acontactIdentity object plus a full contact object, which includes all of the new contact’s properties.
contact.unsubscribed
Sent when- a contact is unsubscribed from your audience.
- 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).
contactIdentity object.
contact.deleted
Sent when a contact is deleted from your audience. Contains acontactIdentity object.
contact.mailingList.subscribed
Sent when a contact is subscribed to a mailing list. ContainscontactIdentity and mailingList objects.
contact.mailingList.unsubscribed
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.
contactIdentity and mailingList objects.
Email sending
campaign.email.sent
Sent when a campaign is sent to a contact.This event will fire for every campaign send. If you send a campaign to 1,000
contacts, you will receive 1,000 events.
campaignId and campaignName values plus contactIdentity and email objects.
If the campaign was sent to one or more mailing lists, a mailingLists list will also be included.
loop.email.sent
Sent when a workflow email is sent to a contact.This event keeps its pre-May 6, 2026
loop name for compatibility.This event will fire for every contact in a workflow. If 1,000 contacts get
sent emails from your workflow, you will receive 1,000 events.
loopId and loopName values plus contactIdentity and email objects.
If the workflow was sent to one or more mailing lists, a mailingLists list will also be included.
transactional.email.sent
Sent when a transactional email is sent. Contains atransactionalId value plus contactIdentity and email objects.
Email events
email.delivered
Sent when an email is delivered to its recipient. Contains asourceType and a related campaignId / transactionalId / loopId value, plus contactIdentity and email objects.
email.softBounced
Sent when an email soft bounces. Contains asourceType and a related campaignId / transactionalId / loopId value, plus contactIdentity and email objects.
email.hardBounced
Sent when an email hard bounces. In Loops, a hard bounce results in a contact being unsubscribed from your audience so acontact.unsubscribed event will also be sent.
Contains a sourceType and a related campaignId / transactionalId / loopId value, plus contactIdentity and email objects.
email.opened
Sent when a campaign or workflow email is opened. Contains asourceType and a related campaignId or loopId value, plus contactIdentity and email objects.
This event is not available for transactional emails because email opens are
not tracked for transactional emails.
email.clicked
Sent when a link in a campaign or workflow email is clicked. Contains asourceType and a related campaignId or loopId value, plus contactIdentity and email objects.
This event is not available for transactional emails because link clicks are
not tracked in transactional emails.
email.unsubscribed
Sent when a recipient unsubscribes from marketing email or a mailing list using an email’s “Unsubscribe” link. Acontact.unsubscribed or contact.mailingList.unsubscribed event will also be sent depending on whether the email was sent to a mailing list or not.
Contains a sourceType and a related campaignId or loopId value, plus contactIdentity and email objects.
This event is not available for transactional emails because unsubscribe links
are not included or required for
transactional emails.
email.resubscribed
Sent when a recipient resubscribes to marketing email from an email’s preference center (“Unsubscribe” link). Contains asourceType and a related campaignId or loopId value, plus contactIdentity and email objects.
This event is not available for transactional emails because unsubscribe links
are not included or required for
transactional emails.
email.spamReported
Sent when a recipient reports your email as spam. Contains asourceType and a related campaignId / transactionalId / loopId value, plus contactIdentity and email objects.

