> ## Documentation Index
> Fetch the complete documentation index at: https://sendmux.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a webhook subscription

> Creates a new webhook subscription and returns the signing secret ONCE in the response body. Store it securely — it cannot be retrieved later. Use `POST /webhooks/{id}/rotate-secret` to issue a new one.

Supply an `Idempotency-Key` header (any unique string, max 255 chars) to safely retry on network errors. Replays with the same key return the original response; replays with a different body return `409 idempotency_conflict`.



## OpenAPI

````yaml /openapi-app.json post /webhooks
openapi: 3.1.0
info:
  description: Programmatic access to your Sendmux email infrastructure.
  title: Sendmux API
  version: 1.0.0
servers:
  - description: API v1
    url: https://app.sendmux.ai/api/v1
security:
  - bearerAuth: []
paths:
  /webhooks:
    post:
      tags:
        - Webhooks
      summary: Create a webhook subscription
      description: >-
        Creates a new webhook subscription and returns the signing secret ONCE
        in the response body. Store it securely — it cannot be retrieved later.
        Use `POST /webhooks/{id}/rotate-secret` to issue a new one.


        Supply an `Idempotency-Key` header (any unique string, max 255 chars) to
        safely retry on network errors. Replays with the same key return the
        original response; replays with a different body return `409
        idempotency_conflict`.
      operationId: managementCreateWebhook
      parameters:
        - in: header
          name: Idempotency-Key
          required: false
          schema:
            description: >-
              Client-chosen unique key to safely retry the request. Cached for
              24h per (team, endpoint, key). Different body with same key
              returns 409 idempotency_conflict.
            example: webhooks-create-20260424-001
            maxLength: 255
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookCreateBody'
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookSubscriptionWithSecretResponse'
          description: >-
            Subscription created, including the signing secret. The response
            carries a `Location` header pointing at the canonical GET URL for
            the new subscription.
          headers:
            Location:
              description: Canonical GET URL for the newly created webhook subscription.
              schema:
                example: /api/v1/webhooks/whk_clxxxxxxxxxxxxxxxxxxxxxxxxx
                type: string
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          description: Invalid request body
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          description: Authentication required
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          description: Insufficient permissions
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          description: >-
            `Idempotency-Key` was replayed with a different body
            (`idempotency_conflict`).
        '413':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          description: Request body too large
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
          description: Validation failed (e.g. non-https URL, unknown event type)
      security:
        - bearerAuth: []
components:
  schemas:
    WebhookCreateBody:
      additionalProperties: false
      properties:
        enabled:
          description: Defaults to true.
          example: true
          type: boolean
        event_types:
          description: At least one event type must be provided.
          example:
            - message.bounced
            - message.received
          items:
            description: >-
              Event types a webhook may subscribe to. `sendmux.test` is accepted
              so you can verify end-to-end delivery via POST
              /webhooks/{id}/test.
            enum:
              - message.delivered
              - message.bounced
              - message.complained
              - message.rejected
              - message.delivery_delayed
              - message.received
              - message.received.spam
              - sendmux.test
            example: message.bounced
            type: string
          minItems: 1
          type: array
        filters:
          allOf:
            - $ref: '#/components/schemas/WebhookFilters'
            - description: >-
                Optional delivery scope. Omit or pass an empty mailbox_ids array
                to receive matching events for all mailboxes in the team.
        name:
          description: >-
            Optional human-friendly label (max 255 chars). Surfaced in dashboard
            list/detail views.
          example: Acme inbound forwarder
          maxLength: 255
          minLength: 1
          type: string
        url:
          description: >-
            HTTPS endpoint that will receive event POSTs. Must be https:// —
            plain HTTP is rejected.
          example: https://hooks.acme.com/sendmux
          format: uri
          type: string
      required:
        - url
        - event_types
      type: object
    WebhookSubscriptionWithSecretResponse:
      allOf:
        - $ref: '#/components/schemas/SuccessEnvelope'
        - properties:
            data:
              $ref: '#/components/schemas/WebhookSubscriptionWithSecret'
            meta:
              $ref: '#/components/schemas/ResponseMeta'
          required:
            - data
          type: object
      unevaluatedProperties: false
    ApiError:
      additionalProperties: false
      properties:
        error:
          additionalProperties: false
          properties:
            code:
              description: Machine-readable error code
              enum:
                - invalid_parameter
                - missing_parameter
                - authentication_required
                - insufficient_permissions
                - not_found
                - conflict
                - limit_exceeded
                - idempotency_conflict
                - payload_too_large
                - validation_error
                - rate_limit_exceeded
                - service_unavailable
                - internal_error
              example: invalid_parameter
              type: string
            doc_url:
              description: Link to relevant documentation
              type: string
            errors:
              description: >-
                Accumulated per-field issues for validation errors. Only present
                on 400/422 responses.
              items:
                $ref: '#/components/schemas/ApiErrorDetail'
              type: array
            message:
              description: Human-readable error description
              type: string
            param:
              description: The parameter that caused the error
              type: string
            retryable:
              description: >-
                Whether the caller may safely retry this request. 4xx are
                typically false (except 429); 5xx are typically true.
              example: false
              type: boolean
          required:
            - code
            - message
            - retryable
          type: object
        meta:
          additionalProperties: false
          properties:
            request_id:
              example: req_clxxxxxxxxxxxxxxxxxxxxxxxxx
              type: string
          required:
            - request_id
          type: object
        ok:
          enum:
            - false
          type: boolean
      required:
        - ok
        - error
        - meta
      type: object
    WebhookFilters:
      additionalProperties: false
      description: Optional delivery scope. Empty mailbox_ids means all team mailboxes.
      properties:
        mailbox_ids:
          description: >-
            Mailbox public IDs to receive events for. Empty means all mailboxes
            in the team.
          example:
            - mbx_clxxxxxxxxxxxxxxxxxxxxxxxxx
          items:
            type: string
          type: array
      required:
        - mailbox_ids
      type: object
    SuccessEnvelope:
      properties:
        meta:
          additionalProperties: {}
          properties: {}
          type: object
        ok:
          enum:
            - true
          type: boolean
      required:
        - ok
        - meta
      type: object
    WebhookSubscriptionWithSecret:
      allOf:
        - $ref: '#/components/schemas/WebhookSubscription'
        - additionalProperties: false
          properties:
            secret:
              description: >-
                Signing secret used to verify the HMAC-SHA256 signature on every
                event POST. This is the ONLY response containing the raw secret
                — store it securely; it cannot be retrieved later. Use POST
                /webhooks/{id}/rotate-secret to issue a new one.
              example: whsec_a9f3c2…
              type: string
          required:
            - secret
          type: object
    ResponseMeta:
      additionalProperties: false
      properties:
        request_id:
          example: req_clxxxxxxxxxxxxxxxxxxxxxxxxx
          type: string
      required:
        - request_id
      type: object
    ApiErrorDetail:
      additionalProperties: false
      properties:
        code:
          description: >-
            Machine-readable issue code from the validator (e.g. zod issue
            code).
          example: invalid_string
          type: string
        field:
          description: Dot-path of the offending request field.
          example: recipient.email
          type: string
        message:
          description: Human-readable issue description.
          type: string
      required:
        - field
        - code
        - message
      type: object
    WebhookSubscription:
      additionalProperties: false
      properties:
        created_at:
          description: ISO 8601 creation timestamp
          example: '2026-04-23T09:12:00Z'
          type: string
        enabled:
          description: When false, no events are delivered to this subscription.
          example: true
          type: boolean
        event_types:
          description: Event types this subscription receives.
          example:
            - message.bounced
            - message.received
          items:
            description: >-
              Event types a webhook may subscribe to. `sendmux.test` is accepted
              so you can verify end-to-end delivery via POST
              /webhooks/{id}/test.
            enum:
              - message.delivered
              - message.bounced
              - message.complained
              - message.rejected
              - message.delivery_delayed
              - message.received
              - message.received.spam
              - sendmux.test
            example: message.bounced
            type: string
          type: array
        failing:
          description: >-
            True when the 24-hour retry window has been exhausted for this
            subscription. Reset by updating the subscription (e.g. fixing the
            URL) and re-enabling.
          example: false
          type: boolean
        filters:
          $ref: '#/components/schemas/WebhookFilters'
        id:
          description: Webhook public ID
          example: whk_clxxxxxxxxxxxxxxxxxxxxxxxxx
          type: string
        name:
          description: >-
            Optional human-friendly label used in dashboard list/detail pages.
            May be `null` for subscriptions created without a name.
          example: Acme inbound forwarder
          type:
            - string
            - 'null'
        updated_at:
          description: ISO 8601 last-modified timestamp
          example: '2026-04-23T09:12:00Z'
          type: string
        url:
          description: HTTPS endpoint that receives signed event POSTs.
          example: https://hooks.acme.com/sendmux
          format: uri
          type: string
      required:
        - id
        - name
        - url
        - event_types
        - filters
        - enabled
        - failing
        - created_at
        - updated_at
      type: object
  securitySchemes:
    bearerAuth:
      bearerFormat: API Key
      description: >-
        Sendmux API key. Use a root API key for Management API routes, or a
        mailbox credential for Mailbox API routes. Obtain keys from the
        dashboard under API Keys.
      scheme: bearer
      type: http

````