Loops Webhooks API

Events Loops sends to your configured webhook endpoint when certain events happen in your account. Configure an endpoint in Settings → Webhooks. Each account supports one webhook endpoint. Events are signed with `webhook-id`, `webhook-timestamp`, and `webhook-signature` headers and delivered at a maximum rate of 10 per second. See https://loops.so/docs/webhooks for setup, verification, and payload details.

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/loops-webhooks-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

loops-webhooks-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Loops OpenAPI Spec Webhooks API
  description: This is the OpenAPI Spec for the [Loops API](https://loops.so/docs/api).
  version: 1.21.6
servers:
- url: https://app.loops.so/api
tags:
- name: Webhooks
  description: Events Loops sends to your configured webhook endpoint when certain events happen in your account. Configure an endpoint in Settings → Webhooks. Each account supports one webhook endpoint. Events are signed with `webhook-id`, `webhook-timestamp`, and `webhook-signature` headers and delivered at a maximum rate of 10 per second. See https://loops.so/docs/webhooks for setup, verification, and payload details.
paths: {}
webhooks:
  contactUnsubscribed:
    post:
      operationId: webhookContactUnsubscribed
      x-excluded: true
      summary: Contact unsubscribed
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookContactUnsubscribedPayload'
            example:
              eventName: contact.unsubscribed
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  contactCreated:
    post:
      operationId: webhookContactCreated
      x-excluded: true
      summary: Contact created
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookContactCreatedPayload'
            example:
              eventName: contact.created
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              contactIdentity:
                id: cm4itta800003ow9hhekzk94o
                email: test+5@loops.so
                userId: null
              contact:
                id: cm4itta800003ow9hhekzk94o
                email: test+5@loops.so
                firstName: null
                lastName: null
                source: API
                subscribed: true
                userGroup: ''
                userId: null
                mailingLists:
                  cm4ittp2k000l12j3lgrzvlxt: true
                optInStatus: accepted
                favoriteColor: blue
                favoriteNumber: 42
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  contactDeleted:
    post:
      operationId: webhookContactDeleted
      x-excluded: true
      summary: Contact deleted
      description: Sent when a contact is deleted from your audience. Contains a `contactIdentity` object.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookContactDeletedPayload'
            example:
              eventName: contact.deleted
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  contactMailingListSubscribed:
    post:
      operationId: webhookContactMailingListSubscribed
      x-excluded: true
      summary: Contact subscribed to mailing list
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookContactMailingListSubscribedPayload'
            example:
              eventName: contact.mailingList.subscribed
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
              mailingList:
                id: cm4ittp2k000l12j3lgrzvlxt
                name: test mailing list
                description: null
                isPublic: true
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  contactMailingListUnsubscribed:
    post:
      operationId: webhookContactMailingListUnsubscribed
      x-excluded: true
      summary: Contact unsubscribed from mailing list
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookContactMailingListUnsubscribedPayload'
            example:
              eventName: contact.mailingList.unsubscribed
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
              mailingList:
                id: cm4ittp2k000l12j3lgrzvlxt
                name: test mailing list
                description: null
                isPublic: true
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  transactionalEmailSent:
    post:
      operationId: webhookTransactionalEmailSent
      x-excluded: true
      summary: Transactional email sent
      description: Sent when a transactional email is sent to a contact. Contains a `transactionalId` value plus `contactIdentity` and `email` objects.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookTransactionalEmailSentPayload'
            example:
              eventName: transactional.email.sent
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
              transactionalId: cm4t1suns001uw6atri87v54s
              transactionalName: Test Transactional
              email:
                id: cm4t1sseg004tje7982991nan
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  campaignEmailSent:
    post:
      operationId: webhookCampaignEmailSent
      x-excluded: true
      summary: Campaign email sent
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookCampaignEmailSentPayload'
            example:
              eventName: campaign.email.sent
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
              campaignId: cm4t1suns001uw6atri87v54s
              campaignName: Test Campaign
              email:
                id: cm4t1sv84004yje79hawr1fi1
                emailMessageId: cm4t1suns001ww6atotin3bn1
                subject: Test Subject
              mailingLists:
              - id: cm4ittp2k000l12j3lgrzvlxt
                name: test mailing list
                description: null
                isPublic: true
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  loopEmailSent:
    post:
      operationId: webhookLoopEmailSent
      x-excluded: true
      summary: Loop email sent
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookLoopEmailSentPayload'
            example:
              eventName: loop.email.sent
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
              loopId: cm4t1snfj0052icemfshgqfcw
              loopName: Test Loop
              email:
                id: cm4t1socj004mje79e61mgh7d
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
              mailingLists:
              - id: cm4ittp2k000l12j3lgrzvlxt
                name: test mailing list
                description: null
                isPublic: true
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  emailDelivered:
    post:
      operationId: webhookEmailDelivered
      x-excluded: true
      summary: Email delivered
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEmailDeliveredPayload'
            example:
              eventName: email.delivered
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              sourceType: campaign
              campaignId: cm4t1suns001uw6atri87v54s
              email:
                id: cm4t1sseg004tje7982991nan
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  emailSoftBounced:
    post:
      operationId: webhookEmailSoftBounced
      x-excluded: true
      summary: Email soft bounced
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEmailSoftBouncedPayload'
            example:
              eventName: email.softBounced
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              sourceType: campaign
              campaignId: cm4t1suns001uw6atri87v54s
              email:
                id: cm4t1sseg004tje7982991nan
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  emailHardBounced:
    post:
      operationId: webhookEmailHardBounced
      x-excluded: true
      summary: Email hard bounced
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEmailHardBouncedPayload'
            example:
              eventName: email.hardBounced
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              sourceType: campaign
              campaignId: cm4t1suns001uw6atri87v54s
              email:
                id: 9874cm4t1sseg004tje7982991nan8732843
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  emailClicked:
    post:
      operationId: webhookEmailClicked
      x-excluded: true
      summary: Email clicked
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEmailClickedPayload'
            example:
              eventName: email.clicked
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              sourceType: campaign
              campaignId: cm4t1suns001uw6atri87v54s
              email:
                id: cm4t1sseg004tje7982991nan
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  emailUnsubscribed:
    post:
      operationId: webhookEmailUnsubscribed
      x-excluded: true
      summary: Email unsubscribed
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEmailUnsubscribedPayload'
            example:
              eventName: email.unsubscribed
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              sourceType: campaign
              campaignId: cm4t1suns001uw6atri87v54s
              email:
                id: cm4t1sseg004tje7982991nan
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  emailResubscribed:
    post:
      operationId: webhookEmailResubscribed
      x-excluded: true
      summary: Email resubscribed
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEmailResubscribedPayload'
            example:
              eventName: email.resubscribed
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              sourceType: campaign
              campaignId: cm4t1suns001uw6atri87v54s
              email:
                id: cm4t1sseg004tje7982991nan
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  emailOpened:
    post:
      operationId: webhookEmailOpened
      x-excluded: true
      summary: Email opened
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEmailOpenedPayload'
            example:
              eventName: email.opened
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              sourceType: campaign
              campaignId: cm4t1suns001uw6atri87v54s
              email:
                id: cm4t1sseg004tje7982991nan
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  emailSpamReported:
    post:
      operationId: webhookEmailSpamReported
      x-excluded: true
      summary: Email spam reported
      description: 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.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookEmailSpamReportedPayload'
            example:
              eventName: email.spamReported
              eventTime: 1734425918
              webhookSchemaVersion: 1.0.0
              sourceType: campaign
              campaignId: cm4t1suns001uw6atri87v54s
              email:
                id: cm4t1sseg004tje7982991nan
                emailMessageId: cm4ittv1v001oow9hruou8na8
                subject: Subject of the email
              contactIdentity:
                id: cm4ittmhq0011ow9h6fb460yw
                email: test@example.com
                userId: null
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
  testingTestEvent:
    post:
      operationId: webhookTestingTestEvent
      x-excluded: true
      summary: Test event
      description: 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`.
      tags:
      - Webhooks
      parameters:
      - $ref: '#/components/parameters/WebhookId'
      - $ref: '#/components/parameters/WebhookTimestamp'
      - $ref: '#/components/parameters/WebhookSignature'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookTestingTestEventPayload'
            example:
              eventName: testing.testEvent
              eventTime: 1734425918
              message: test
              webhookSchemaVersion: 1.0.0
      responses:
        '200':
          description: Webhook received successfully. Return any 2xx status code to acknowledge delivery.
      security: []
components:
  schemas:
    WebhookEmailSpamReportedPayload:
      allOf:
      - $ref: '#/components/schemas/WebhookEmailMetricPayload'
      - type: object
        required:
        - eventName
        properties:
          eventName:
            type: string
            const: email.spamReported
    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'
    WebhookContactMailingListUnsubscribedPayload:
      allOf:
      - $ref: '#/components/schemas/WebhookBasePayload'
      - type: object
        required:
        - eventName
        - mailingList
        properties:
          eventName:
            type: string
            const: contact.mailingList.unsubscribed
          mailingList:
            $ref: '#/components/schemas/WebhookMailingList'
    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'
    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.
    WebhookEmailDeliveredPayload:
      allOf:
      - $ref: '#/components/schemas/WebhookEmailMetricPayload'
      - type: object
        required:
        - eventName
        properties:
          eventName:
            type: string
            const: email.delivered
    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'
    WebhookContactDeletedPayload:
      allOf:
      - $ref: '#/components/schemas/WebhookBasePayload'
      - type: object
        required:
        - eventName
        properties:
          eventName:
            type: string
            const: contact.deleted
    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.
    WebhookEmailClickedPayload:
      allOf:
      - $ref: '#/components/schemas/WebhookMarketingEmailMetricPayload'
      - type: object
        required:
        - eventName
        properties:
          eventName:
            type: string
            const: email.clicked
    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
    WebhookContactCreatedPayload:
      allOf:
      - $ref: '#/components/schemas/WebhookBasePayload'
      - type: object
        required:
        - eventName
        - contact
        properties:
          eventName:
            type: string
            const: contact.created
          contact:
            $ref: '#/components/schemas/WebhookContact'
    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
    WebhookContactIdentity:
      type: object
      required:
      - id
      - email
      - userId
      properties:
        id:
          type: string
        email:
          type: st

# --- truncated at 32 KB (37 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/loops/refs/heads/main/openapi/loops-webhooks-api-openapi.yml