Resend · AsyncAPI Specification

Resend Webhooks

Version 1.0.0

AsyncAPI 2.6 description of the Resend webhook surface. Resend delivers webhook events to subscriber-configured HTTPS endpoints using Svix as the underlying delivery and signing infrastructure. Every request carries `svix-id`, `svix-timestamp`, and `svix-signature` headers. The payload is a consistent envelope of `type`, `created_at`, and `data`, where `data` varies by event type. Subscribers verify the signature with their Svix signing secret, dedupe by `svix-id`, and dispatch on `type`. Source: https://resend.com/docs/dashboard/webhooks/introduction and https://resend.com/docs/dashboard/webhooks/event-types

View Spec View on GitHub EmailDeveloper ToolsTransactional EmailMarketing EmailAsyncAPIWebhooksEvents

Channels

/
publish receiveResendWebhook
Receive a Resend webhook event
A single subscriber endpoint receives every Resend webhook event for which it has been subscribed in the dashboard. The event kind is discriminated by the `type` field in the JSON envelope.

Messages

EmailSent
email.sent
The API request to send the email was successful.
EmailDelivered
email.delivered
The receiving mail server accepted the message for delivery.
EmailDeliveryDelayed
email.delivery_delayed
The email could not be delivered due to a temporary issue. Resend will keep retrying.
EmailComplained
email.complained
The email was delivered but the recipient marked it as spam.
EmailBounced
email.bounced
The receiving mail server permanently rejected the message.
EmailOpened
email.opened
The recipient opened the email.
EmailClicked
email.clicked
The recipient clicked a tracked link in the email.
ContactCreated
contact.created
A contact was created in an audience.
ContactDeleted
contact.deleted
A contact was deleted from an audience.
ContactUpdated
contact.updated
A contact was updated.
DomainCreated
domain.created
A sending domain was created.
DomainDeleted
domain.deleted
A sending domain was deleted.
DomainUpdated
domain.updated
A sending domain was updated. This is also emitted as DNS records are verified and the domain status transitions.

Servers

https
subscriber {subscriberEndpoint}
The HTTPS endpoint owned and operated by the webhook subscriber. Resend (via Svix) sends HTTP POST requests carrying signed webhook envelopes to this URL. The URL is configured in the Resend dashboard under Webhooks.

AsyncAPI Specification

Raw ↑
asyncapi: '2.6.0'
id: 'urn:com:resend:webhooks'
info:
  title: Resend Webhooks
  version: '1.0.0'
  description: >-
    AsyncAPI 2.6 description of the Resend webhook surface. Resend delivers
    webhook events to subscriber-configured HTTPS endpoints using Svix as the
    underlying delivery and signing infrastructure. Every request carries
    `svix-id`, `svix-timestamp`, and `svix-signature` headers. The payload is a
    consistent envelope of `type`, `created_at`, and `data`, where `data`
    varies by event type. Subscribers verify the signature with their Svix
    signing secret, dedupe by `svix-id`, and dispatch on `type`.

    Source: https://resend.com/docs/dashboard/webhooks/introduction
    and https://resend.com/docs/dashboard/webhooks/event-types
  contact:
    name: Resend Support
    url: https://resend.com/docs/support
  license:
    name: Proprietary
    url: https://resend.com/legal/terms-of-service
  termsOfService: https://resend.com/legal/terms-of-service
  x-apis-json:
    aid: resend:resend:webhooks
    humanURL: https://resend.com/docs/dashboard/webhooks/introduction

defaultContentType: application/json

servers:
  subscriber:
    url: '{subscriberEndpoint}'
    protocol: https
    description: >-
      The HTTPS endpoint owned and operated by the webhook subscriber. Resend
      (via Svix) sends HTTP POST requests carrying signed webhook envelopes to
      this URL. The URL is configured in the Resend dashboard under Webhooks.
    variables:
      subscriberEndpoint:
        default: https://example.com/webhooks/resend
        description: The fully qualified HTTPS URL of the subscriber receiver.

channels:
  /:
    description: >-
      A single subscriber endpoint receives every Resend webhook event for
      which it has been subscribed in the dashboard. The event kind is
      discriminated by the `type` field in the JSON envelope.
    bindings:
      http:
        type: request
        method: POST
        bindingVersion: '0.3.0'
    publish:
      operationId: receiveResendWebhook
      summary: Receive a Resend webhook event
      description: >-
        Resend POSTs a signed Svix envelope to the subscriber endpoint. The
        subscriber must verify the `svix-signature` header against the request
        body and the Svix signing secret before trusting any field. Use
        `svix-id` to dedupe replays. Dispatch the event by inspecting the
        envelope `type`.
      message:
        oneOf:
          - $ref: '#/components/messages/EmailSent'
          - $ref: '#/components/messages/EmailDelivered'
          - $ref: '#/components/messages/EmailDeliveryDelayed'
          - $ref: '#/components/messages/EmailComplained'
          - $ref: '#/components/messages/EmailBounced'
          - $ref: '#/components/messages/EmailOpened'
          - $ref: '#/components/messages/EmailClicked'
          - $ref: '#/components/messages/ContactCreated'
          - $ref: '#/components/messages/ContactDeleted'
          - $ref: '#/components/messages/ContactUpdated'
          - $ref: '#/components/messages/DomainCreated'
          - $ref: '#/components/messages/DomainDeleted'
          - $ref: '#/components/messages/DomainUpdated'

components:
  messageTraits:
    SvixSignedEnvelope:
      headers:
        type: object
        required:
          - svix-id
          - svix-timestamp
          - svix-signature
        properties:
          svix-id:
            type: string
            description: >-
              Unique identifier for the webhook message. Use this value to
              dedupe events on the subscriber side; Svix may redeliver on
              failure.
            examples:
              - msg_p5jXN8AQM9LWM0D4loKWxJek
          svix-timestamp:
            type: string
            description: >-
              Unix epoch seconds when the webhook was dispatched. Reject
              messages whose timestamp drifts too far from the current time
              to mitigate replay.
            examples:
              - '1614265330'
          svix-signature:
            type: string
            description: >-
              Space-separated list of one or more signatures of the form
              `v1,<base64>` computed by Svix over `svix-id.svix-timestamp.body`
              using the endpoint signing secret. At least one signature must
              verify.
            examples:
              - v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=
      bindings:
        http:
          headers:
            type: object
            properties:
              content-type:
                type: string
                const: application/json
          bindingVersion: '0.3.0'

  messages:
    EmailSent:
      name: EmailSent
      title: email.sent
      summary: The API request to send the email was successful.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/EmailSentEnvelope'

    EmailDelivered:
      name: EmailDelivered
      title: email.delivered
      summary: The receiving mail server accepted the message for delivery.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/EmailDeliveredEnvelope'

    EmailDeliveryDelayed:
      name: EmailDeliveryDelayed
      title: email.delivery_delayed
      summary: >-
        The email could not be delivered due to a temporary issue. Resend will
        keep retrying.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/EmailDeliveryDelayedEnvelope'

    EmailComplained:
      name: EmailComplained
      title: email.complained
      summary: >-
        The email was delivered but the recipient marked it as spam.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/EmailComplainedEnvelope'

    EmailBounced:
      name: EmailBounced
      title: email.bounced
      summary: The receiving mail server permanently rejected the message.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/EmailBouncedEnvelope'

    EmailOpened:
      name: EmailOpened
      title: email.opened
      summary: The recipient opened the email.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/EmailOpenedEnvelope'

    EmailClicked:
      name: EmailClicked
      title: email.clicked
      summary: The recipient clicked a tracked link in the email.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/EmailClickedEnvelope'

    ContactCreated:
      name: ContactCreated
      title: contact.created
      summary: A contact was created in an audience.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/ContactCreatedEnvelope'

    ContactDeleted:
      name: ContactDeleted
      title: contact.deleted
      summary: A contact was deleted from an audience.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/ContactDeletedEnvelope'

    ContactUpdated:
      name: ContactUpdated
      title: contact.updated
      summary: A contact was updated.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/ContactUpdatedEnvelope'

    DomainCreated:
      name: DomainCreated
      title: domain.created
      summary: A sending domain was created.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/DomainCreatedEnvelope'

    DomainDeleted:
      name: DomainDeleted
      title: domain.deleted
      summary: A sending domain was deleted.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/DomainDeletedEnvelope'

    DomainUpdated:
      name: DomainUpdated
      title: domain.updated
      summary: >-
        A sending domain was updated. This is also emitted as DNS records are
        verified and the domain status transitions.
      contentType: application/json
      traits:
        - $ref: '#/components/messageTraits/SvixSignedEnvelope'
      payload:
        $ref: '#/components/schemas/DomainUpdatedEnvelope'

  schemas:
    Envelope:
      type: object
      description: >-
        Common Resend webhook envelope. The `type` field discriminates the
        event and dictates the shape of `data`.
      required:
        - type
        - created_at
        - data
      properties:
        type:
          type: string
          description: The event type. See concrete envelope schemas for enumerated values.
        created_at:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the webhook event was created.
        data:
          type: object
          description: Event-specific payload. See per-event schemas.

    EmailEventData:
      type: object
      description: >-
        Common email-event `data` body shared by email.sent, email.delivered,
        email.delivery_delayed, email.complained, email.opened.
      properties:
        broadcast_id:
          type: string
          format: uuid
          description: >-
            Identifier of the broadcast this email belongs to, when sent as
            part of a broadcast.
          examples:
            - 8b146471-e88e-4322-86af-016cd36fd216
        created_at:
          type: string
          description: When the email was created by Resend.
          examples:
            - '2026-02-22T23:41:11.894719+00:00'
        email_id:
          type: string
          format: uuid
          description: The Resend email ID.
          examples:
            - 56761188-7520-42d8-8898-ff6fc54ce618
        from:
          type: string
          description: The email's `From` header value.
          examples:
            - Acme <[email protected]>
        to:
          type: array
          items:
            type: string
            format: email
          description: Recipient email addresses.
          examples:
            - ['[email protected]']
        subject:
          type: string
          description: Email subject line.
          examples:
            - Sending this example
        template_id:
          type: string
          format: uuid
          description: Template identifier, when the email was sent from a template.
          examples:
            - 43f68331-0622-4e15-8202-246a0388854b
        tags:
          type: object
          description: Custom key/value tags attached to the email at send time.
          additionalProperties:
            type: string
          examples:
            - { category: confirm_email }

    Bounce:
      type: object
      description: Bounce details emitted with email.bounced events.
      properties:
        diagnosticCode:
          type: array
          items:
            type: string
          description: Raw SMTP diagnostic codes returned by the receiving server.
          examples:
            - ['smtp; 550 5.5.0 Requested action not taken: mailbox unavailable']
        message:
          type: string
          description: Human-readable explanation of why the email bounced.
          examples:
            - "The recipient's email address is on the suppression list because it has a recent history of producing hard bounces."
        subType:
          type: string
          description: Bounce sub-classification (for example `Suppressed`, `General`).
          examples:
            - Suppressed
        type:
          type: string
          description: Bounce classification.
          examples:
            - Permanent

    Click:
      type: object
      description: Click details emitted with email.clicked events.
      properties:
        ipAddress:
          type: string
          description: IP address from which the click occurred.
          examples:
            - 122.115.53.11
        link:
          type: string
          format: uri
          description: The URL that was clicked.
          examples:
            - https://resend.com
        timestamp:
          type: string
          format: date-time
          description: When the click was observed.
          examples:
            - '2026-11-24T05:00:57.163Z'
        userAgent:
          type: string
          description: The User-Agent string of the clicking client.
          examples:
            - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Safari/605.1.15

    Contact:
      type: object
      description: Contact `data` shared by contact.created, contact.updated, contact.deleted.
      properties:
        id:
          type: string
          format: uuid
          description: Contact ID.
          examples:
            - e169aa45-1ecf-4183-9955-b1499d5701d3
        audience_id:
          type: string
          format: uuid
          description: The audience the contact belongs to.
          examples:
            - 78261eea-8f8b-4381-83c6-79fa7120f1cf
        segment_ids:
          type: array
          description: Segments the contact is a member of.
          items:
            type: string
            format: uuid
          examples:
            - ['78261eea-8f8b-4381-83c6-79fa7120f1cf']
        created_at:
          type: string
          format: date-time
          description: When the contact was created.
        updated_at:
          type: string
          format: date-time
          description: When the contact was last updated.
        email:
          type: string
          format: email
          description: Contact email address.
          examples:
            - [email protected]
        first_name:
          type: string
          description: Contact first name.
          examples:
            - Steve
        last_name:
          type: string
          description: Contact last name.
          examples:
            - Wozniak
        unsubscribed:
          type: boolean
          description: Whether the contact has unsubscribed.
          examples:
            - false

    DomainRecord:
      type: object
      description: A single DNS record entry attached to a domain.
      properties:
        record:
          type: string
          description: The role of the record (for example SPF, DKIM, Receiving MX).
        name:
          type: string
          description: Record name.
        type:
          type: string
          description: DNS record type (MX, TXT, CNAME, etc.).
        ttl:
          type: string
          description: TTL value as advertised by Resend (often `Auto`).
        status:
          type: string
          description: Verification status of this record.
        value:
          type: string
          description: Record value.
        priority:
          type: integer
          description: Priority for records that support it (for example MX).

    Domain:
      type: object
      description: Domain `data` shared by domain.created, domain.updated, domain.deleted.
      properties:
        id:
          type: string
          format: uuid
          description: Domain ID.
          examples:
            - d91cd9bd-1176-453e-8fc1-35364d380206
        name:
          type: string
          description: The domain name.
          examples:
            - example.com
        status:
          type: string
          description: >-
            Verification status. Documented values include `not_started`,
            `pending`, `verified`, `partially_verified`, `partially_failed`,
            and `failed`.
          examples:
            - not_started
        created_at:
          type: string
          description: When the domain record was created.
          examples:
            - '2026-04-26T20:21:26.347412+00:00'
        region:
          type: string
          description: The sending region for the domain.
          examples:
            - us-east-1
        records:
          type: array
          description: DNS records associated with the domain.
          items:
            $ref: '#/components/schemas/DomainRecord'

    EmailSentEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: email.sent
            data:
              $ref: '#/components/schemas/EmailEventData'

    EmailDeliveredEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: email.delivered
            data:
              $ref: '#/components/schemas/EmailEventData'

    EmailDeliveryDelayedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: email.delivery_delayed
            data:
              $ref: '#/components/schemas/EmailEventData'

    EmailComplainedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: email.complained
            data:
              $ref: '#/components/schemas/EmailEventData'

    EmailBouncedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: email.bounced
            data:
              allOf:
                - $ref: '#/components/schemas/EmailEventData'
                - type: object
                  properties:
                    bounce:
                      $ref: '#/components/schemas/Bounce'

    EmailOpenedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: email.opened
            data:
              $ref: '#/components/schemas/EmailEventData'

    EmailClickedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: email.clicked
            data:
              allOf:
                - $ref: '#/components/schemas/EmailEventData'
                - type: object
                  properties:
                    click:
                      $ref: '#/components/schemas/Click'

    ContactCreatedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: contact.created
            data:
              $ref: '#/components/schemas/Contact'

    ContactDeletedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: contact.deleted
            data:
              $ref: '#/components/schemas/Contact'

    ContactUpdatedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: contact.updated
            data:
              $ref: '#/components/schemas/Contact'

    DomainCreatedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: domain.created
            data:
              $ref: '#/components/schemas/Domain'

    DomainDeletedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: domain.deleted
            data:
              $ref: '#/components/schemas/Domain'

    DomainUpdatedEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - type: object
          properties:
            type:
              type: string
              const: domain.updated
            data:
              $ref: '#/components/schemas/Domain'