openapi: 3.0.0
info:
  title: Paubox Email API
  description: >
    Public documentation for Paubox's Transactional Email API


    ## Authentication


    **IMPORTANT**: This API uses a custom authentication format that requires
    the "Token token=" prefix.


    All requests must include the Authorization header in this exact format:

    ```

    Authorization: Token token=YOUR_API_KEY

    ```


    **Note for Code Generation Tools**: Auto-generated code from this
    specification may need to be modified to include the "Token token=" prefix,
    as most generators expect standard Bearer token format.
  version: 1.0.0
servers:
  - url: https://api.paubox.com/v1/email
    description: Paubox Email API
security:
  - PauboxToken: []
tags:
  - name: Messages
    description: Send individual or bulk transactional email
  - name: Scheduled Send
    description: Schedule, check, reschedule, and cancel future email delivery
  - name: Dynamic Templates
    description: Manage and use dynamic Handlebars templates for email content
  - name: Receiving
    description: Receive inbound email — manage domains, mailboxes, and retrieve messages
  - name: Webhooks
    description: Manage webhook endpoints for delivery and inbound event notifications
paths:
  /messages:
    post:
      tags:
        - Messages
      summary: Send a single email message
      description: Send a single HIPAA compliant email with the Paubox Email API. Supports cc, bcc, custom headers, attachments, and open and link tracking overrides.
      operationId: sendMessage
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SingleSendRequest'
            examples:
              basic:
                summary: Minimal text+HTML example
                description: |
                  **CURL Example:**
                  ```bash
                  curl --request POST \
                    --url https://api.paubox.com/v1/email/messages \
                    --header 'Authorization: Token token=YOUR_API_KEY' \
                    --header 'Content-Type: application/json' \
                    --data '{"data":{"message":{"recipients":["recipient@host.com"],"headers":{"subject":"Hello from the Paubox Email API","from":"sender@verifieddomain.com"},"content":{"text/plain":"Hello world","text/html":"<html><body><h1>Hello world</h1></body></html>"}}}}'
                  ```
                value:
                  data:
                    message:
                      recipients:
                        - recipient@host.com
                      headers:
                        subject: Hello from the Paubox Email API
                        from: sender@verifieddomain.com
                      content:
                        text/plain: Hello world
                        text/html: <html><body><h1>Hello world</h1></body></html>
              full:
                summary: >-
                  Full example with bcc, reply-to, custom header, attachment,
                  and overrides
                value:
                  data:
                    message:
                      recipients:
                        - recipient@host.com
                        - Recipient Name <recipient2@host.com>
                      bcc:
                        - recipient3@host.com
                        - Recipient Name <recipient4@host.com>
                      cc:
                        - cc.name <cc@example.com>
                      headers:
                        subject: sample email
                        from: sender@authorized_domain.com
                        reply-to: Sender Name <sender@authorized_domain.com>
                        x-custom-header: sample custom header
                        List-Unsubscribe: >-
                          <mailto:unsubscribe@yourdomain.com?subject=unsubscribe>
                      content:
                        text/plain: Hello World!
                        text/html: <html><body><h1>Hello World!</h1></body></html>
                      attachments:
                        - fileName: hello_world.txt
                          contentType: text/plain
                          content: SGVsbG8gV29ybGQh
                    override_open_tracking: true
                    override_link_tracking: true
                    unsubscribe_url: https://your_url_here.com
        required: true
      responses:
        '200':
          description: Message accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SingleSendResponse'
              examples:
                ok:
                  value:
                    sourceTrackingId: 3d38ab13-0af8-4028-bd45-52e882e0d584
                    customHeaders:
                      X-Custom-Header: value
                    data: Service OK
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /bulk_messages:
    post:
      tags:
        - Messages
      summary: Send multiple email messages (batch)
      description: >
        Sends multiple messages in one request. Paubox recommends batches of 50
        or fewer. Source tracking IDs are returned in the same order as the
        messages array.
      operationId: sendBulkMessages
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkSendRequest'
            examples:
              twoMessages:
                summary: Two-message batch
                value:
                  data:
                    messages:
                      - recipients:
                          - recipient@host.com
                          - Recipient Name <recipient@host.com>
                        bcc:
                          - recipient3@host.com
                          - Recipient Name <recipient4@host.com>
                        headers:
                          subject: sample email
                          from: sender@authorized_domain.com
                          reply-to: Sender Name <sender@authorized_domain.com>
                          x-custom-header: sample custom header
                        content:
                          text/plain: Hello World!
                          text/html: <html><body><h1>Hello World!</h1></body></html>
                        attachments:
                          - fileName: hello_world.txt
                            contentType: text/plain
                            content: SGVsbG8gV29ybGQh
                        allowNonTLS: false
                        forceSecureNotification: false
                      - recipients:
                          - recipient2@host.com
                          - Recipient Name <recipient2@host.com>
                        headers:
                          subject: sample email
                          from: sender@authorized_domain.com
                          reply-to: Sender Name <sender@authorized_domain.com>
                        content:
                          text/plain: Hello World!
                          text/html: <html><body><h1>Hello World!</h1></body></html>
                        attachments:
                          - fileName: hello_world.txt
                            contentType: text/plain
                            content: SGVsbG8gV29ybGQh
        required: true
      responses:
        '200':
          description: Batch accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BulkSendResponse'
              examples:
                ok:
                  value:
                    messages:
                      - sourceTrackingId: 3d38ab13-0af8-4028-bd45-999999999999
                        customHeaders:
                          X-Custom-Header: value
                        data: Service OK
                      - sourceTrackingId: 3d38ab13-0af8-4028-bd45-000000000000
                        customHeaders:
                          X-Custom-Header: value
                        data: Service OK
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /message_receipt:
    get:
      tags:
        - Messages
      summary: Get email disposition
      description: >-
        Retrieve delivery status, open tracking, and click tracking information
        for a sent message
      operationId: getMessageReceipt
      parameters:
        - name: sourceTrackingId
          in: query
          description: The tracking ID returned when the message was sent
          required: true
          schema:
            type: string
            format: uuid
            example: 6e1cf9a4-7bde-4834-8200-ed424b50c8a7
      responses:
        '200':
          description: Message disposition data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageReceiptResponse'
              examples:
                delivered:
                  summary: Delivered message with open and click tracking
                  value:
                    sourceTrackingId: 6e1cf9a4-7bde-4834-8200-ed424b50c8a7
                    data:
                      message:
                        id: >-
                          <f4a9b518-439c-497d-b87f-dfc9cc19194b@authorized_domain.com>
                        message_deliveries:
                          - recipient: recipient@host.com
                            status:
                              deliveryStatus: delivered
                              deliveryTime: Mon, 23 Apr 2018 13:27:34 -0700
                              openedStatus: opened
                              openedTime: Mon, 23 Apr 2018 13:27:51 -0700
                        total_opens: 1
                        distinct_opens: 1
                        total_click_count: 2
                        clicks_per_link:
                          - click_count: 1
                            target_url: amazon.com
                          - click_count: 1
                            target_url: ebay.com
                        unsubscribed: false
        '404':
          description: Message not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageReceiptErrorResponse'
              examples:
                notFound:
                  summary: Message not found
                  value:
                    errors:
                      - code: 404
                        title: Message was not found
                        details: Message with this tracking id was not found
                    sourceTrackingId: 6e1cf9a4-7bde-4834-8d200-ed424b50c8a7
      security:
        - PauboxToken: []
  /dynamic_templates:
    get:
      tags:
        - Dynamic Templates
      summary: List all dynamic templates
      description: Retrieve all dynamic templates for your organization
      operationId: listDynamicTemplates
      responses:
        '200':
          description: List of templates
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DynamicTemplateListResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
    post:
      tags:
        - Dynamic Templates
      summary: Create a dynamic template
      description: Upload a new Handlebars template for dynamic content generation
      operationId: createDynamicTemplate
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/dynamic_templates_body'
        required: true
      responses:
        '200':
          description: Template created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DynamicTemplateResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /dynamic_templates/{id}:
    get:
      tags:
        - Dynamic Templates
      summary: Get a dynamic template
      description: Retrieve a specific dynamic template by ID
      operationId: getDynamicTemplate
      parameters:
        - name: id
          in: path
          description: Template ID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Template details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DynamicTemplateResponse'
        '404':
          description: Template not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
    delete:
      tags:
        - Dynamic Templates
      summary: Delete a dynamic template
      description: Delete a specific dynamic template by ID
      operationId: deleteDynamicTemplate
      parameters:
        - name: id
          in: path
          description: Template ID to delete
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Template deleted successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/inline_response_200'
        '404':
          description: Template not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
    patch:
      tags:
        - Dynamic Templates
      summary: Update a dynamic template
      description: Update an existing Handlebars template
      operationId: updateDynamicTemplate
      parameters:
        - name: id
          in: path
          description: Template ID to update
          required: true
          schema:
            type: string
      requestBody:
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/dynamic_templates_id_body'
        required: true
      responses:
        '200':
          description: Template updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DynamicTemplateResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Template not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /templated_messages:
    post:
      tags:
        - Dynamic Templates
      summary: Send a dynamically templated message
      description: Send an email using a dynamic template with variable substitution
      operationId: sendTemplatedMessage
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplatedMessageRequest'
            examples:
              basic:
                summary: Basic templated message
                value:
                  data:
                    template_name: detailed_test
                    template_values: >-
                      { "name": "Howard",
                      "conditional":"true","items":["one","two","three"] }
                    message:
                      recipients:
                        - recipient@host.com
                        - Recipient Name <recipient2@host.com>
                      bcc:
                        - recipient3@host.com
                        - Recipient Name <recipient4@host.com>
                      headers:
                        subject: sample email
                        from: sender@authorized_domain.com
                        reply-to: Sender Name <sender@authorized_domain.com>
                      allowNonTLS: false
                      forceSecureNotification: false
                      attachments:
                        - fileName: hello_world.txt
                          contentType: text/plain
                          content: SGVsbG8gV29ybGQ
        required: true
      responses:
        '200':
          description: Templated message sent successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SingleSendResponse'
              examples:
                success:
                  value:
                    sourceTrackingId: 3d38ab13-0af8-4028-bd45-XXXXXXXXXXXX
                    data: Service OK
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /schedule:
    post:
      tags:
        - Scheduled Send
      summary: Schedule a message for future delivery
      description: Schedule an email for delivery at a future UTC time, up to 30 days ahead. Returns a sourceTrackingId you can use to check, reschedule, or cancel the send.
      operationId: scheduleMessage
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ScheduleSendRequest'
            examples:
              basic:
                summary: Schedule a message for Christmas
                value:
                  data:
                    message:
                      recipients:
                        - recipient@host.com
                      headers:
                        subject: Holiday greeting
                        from: sender@verifieddomain.com
                      content:
                        text/plain: Happy holidays!
                    scheduled_at: "2025-12-25T15:00:00Z"
        required: true
      responses:
        '200':
          description: Message scheduled successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduleSendResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /schedule/{sourceTrackingId}:
    get:
      tags:
        - Scheduled Send
      summary: Get scheduled message status
      description: Check a scheduled message's state (pending, processing, sent, cancelled, or failed) along with its scheduled, sent, and cancelled times.
      operationId: getScheduledMessage
      parameters:
        - name: sourceTrackingId
          in: path
          required: true
          schema:
            type: string
          description: The sourceTrackingId returned when the message was scheduled
      responses:
        '200':
          description: Scheduled message status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ScheduledMessageStatus'
        '404':
          description: Scheduled message not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
    patch:
      tags:
        - Scheduled Send
      summary: Reschedule a pending message
      description: Move a pending scheduled message to a new send time. The new time must be in the future and within 30 days; only pending messages can be rescheduled.
      operationId: rescheduleMessage
      parameters:
        - name: sourceTrackingId
          in: path
          required: true
          schema:
            type: string
          description: The sourceTrackingId of the scheduled message
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RescheduleRequest'
            examples:
              basic:
                summary: Reschedule to a new time
                value:
                  scheduled_at: "2025-12-26T10:00:00Z"
        required: true
      responses:
        '200':
          description: Message rescheduled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RescheduleResponse'
        '400':
          description: Not found or not in pending state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /schedule/{sourceTrackingId}/cancel:
    post:
      tags:
        - Scheduled Send
      summary: Cancel a pending scheduled message
      description: Cancel a scheduled message before it is sent. Only messages still in the pending state can be cancelled.
      operationId: cancelScheduledMessage
      parameters:
        - name: sourceTrackingId
          in: path
          required: true
          schema:
            type: string
          description: The sourceTrackingId of the scheduled message
      responses:
        '200':
          description: Message cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CancelScheduledResponse'
        '400':
          description: Not found or not in pending state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /receiving/domains:
    get:
      tags:
        - Receiving
      summary: List receiving domains
      description: Returns all receiving domains for the authenticated account.
      operationId: listReceivingDomains
      responses:
        '200':
          description: List of receiving domains
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReceivingDomainListResponse'
      security:
        - PauboxToken: []
    post:
      tags:
        - Receiving
      summary: Create a receiving domain
      description: >
        Provisions a new receiving domain under `inbound.paubox.email`.
        DNS records are configured automatically.
      operationId: createReceivingDomain
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateReceivingDomainRequest'
            examples:
              with_slug:
                summary: Create with a custom slug
                value:
                  slug: support
              auto:
                summary: Auto-generated slug
                value: {}
      responses:
        '201':
          description: Domain created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReceivingDomainResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /receiving/domains/{id}:
    get:
      tags:
        - Receiving
      summary: Get a receiving domain
      description: Retrieve a receiving domain by ID, including its state (active or pending) and the DNS records configured for it.
      operationId: getReceivingDomain
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Domain ID
      responses:
        '200':
          description: Domain details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReceivingDomainResponse'
        '404':
          description: Domain not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
    delete:
      tags:
        - Receiving
      summary: Delete a receiving domain
      description: Delete a receiving domain by ID. Look up domain IDs with the List receiving domains endpoint.
      operationId: deleteReceivingDomain
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Domain ID
      responses:
        '200':
          description: Domain deleted
          content:
            application/json:
              schema:
                type: object
        '404':
          description: Domain not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /receiving/domains/{domain_id}/mailboxes:
    get:
      tags:
        - Receiving
      summary: List mailboxes
      description: Returns all mailboxes for a receiving domain.
      operationId: listMailboxes
      parameters:
        - name: domain_id
          in: path
          required: true
          schema:
            type: integer
          description: Receiving domain ID
      responses:
        '200':
          description: List of mailboxes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MailboxListResponse'
        '404':
          description: Domain not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
    post:
      tags:
        - Receiving
      summary: Create a mailbox
      description: Creates a new mailbox on a receiving domain.
      operationId: createMailbox
      parameters:
        - name: domain_id
          in: path
          required: true
          schema:
            type: integer
          description: Receiving domain ID
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMailboxRequest'
            examples:
              basic:
                summary: Create a support mailbox
                value:
                  name: support
                  password: SecurePass123!
              with_quota:
                summary: Create with a storage quota
                value:
                  name: intake
                  password: SecurePass123!
                  quota_bytes: 1073741824
        required: true
      responses:
        '201':
          description: Mailbox created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MailboxResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /receiving/domains/{domain_id}/mailboxes/{id}:
    get:
      tags:
        - Receiving
      summary: Get a mailbox
      description: Retrieve a mailbox on a receiving domain by ID, including its email address, storage quota, and creation time.
      operationId: getMailbox
      parameters:
        - name: domain_id
          in: path
          required: true
          schema:
            type: integer
          description: Receiving domain ID
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Mailbox ID
      responses:
        '200':
          description: Mailbox details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MailboxResponse'
        '404':
          description: Mailbox not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
    delete:
      tags:
        - Receiving
      summary: Delete a mailbox
      description: Delete a mailbox from a receiving domain. Requires both the receiving domain ID and the mailbox ID.
      operationId: deleteMailbox
      parameters:
        - name: domain_id
          in: path
          required: true
          schema:
            type: integer
          description: Receiving domain ID
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Mailbox ID
      responses:
        '200':
          description: Mailbox deleted
          content:
            application/json:
              schema:
                type: object
        '404':
          description: Mailbox not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /receiving:
    get:
      tags:
        - Receiving
      summary: List received emails
      description: >
        Returns received emails across all active receiving domains,
        sorted by most recent. Supports cursor-based pagination.
      operationId: listReceivedEmails
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 25
            maximum: 100
          description: Maximum number of emails to return (1–100).
        - name: after
          in: query
          schema:
            type: string
          description: Cursor for forward pagination.
        - name: before
          in: query
          schema:
            type: string
          description: Cursor for backward pagination.
      responses:
        '200':
          description: Paginated list of received emails
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReceivedEmailListResponse'
      security:
        - PauboxToken: []
  /receiving/{email_id}:
    get:
      tags:
        - Receiving
      summary: Get a received email
      description: Returns the full content of a single received email, including headers, body, and attachment metadata.
      operationId: getReceivedEmail
      parameters:
        - name: email_id
          in: path
          required: true
          schema:
            type: string
          description: Email ID
      responses:
        '200':
          description: Email details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReceivedEmailResponse'
        '404':
          description: Email not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /receiving/{email_id}/attachments:
    get:
      tags:
        - Receiving
      summary: List email attachments
      description: Returns attachment metadata for a received email.
      operationId: listEmailAttachments
      parameters:
        - name: email_id
          in: path
          required: true
          schema:
            type: string
          description: The email ID
      responses:
        '200':
          description: Attachment metadata list
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ReceivedAttachment'
              example:
                data:
                  - filename: report.pdf
                    content_type: application/pdf
                    size: 12345
                    content_id: null
                    blob_id: abc123
        '404':
          description: Email not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /receiving/{email_id}/attachments/{blob_id}:
    get:
      tags:
        - Receiving
      summary: Download an attachment
      description: Downloads a received email attachment as raw bytes.
      operationId: downloadAttachment
      parameters:
        - name: email_id
          in: path
          required: true
          schema:
            type: string
          description: Email ID
        - name: blob_id
          in: path
          required: true
          schema:
            type: string
          description: Blob ID of the attachment
      responses:
        '200':
          description: Attachment bytes
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
        '404':
          description: Attachment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /webhook_endpoints:
    get:
      tags:
        - Webhooks
      summary: List webhook endpoints
      description: Returns all webhook endpoints for the authenticated account.
      operationId: listWebhookEndpoints
      responses:
        '200':
          description: List of webhook endpoints
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/WebhookEndpoint'
      security:
        - PauboxToken: []
    post:
      tags:
        - Webhooks
      summary: Create a webhook endpoint
      description: >
        Creates a new webhook endpoint that receives event notifications at the
        specified URL.
      operationId: createWebhookEndpoint
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWebhookEndpointRequest'
            examples:
              inbound_only:
                summary: Subscribe to inbound mail events
                value:
                  target_url: https://example.com/webhooks/paubox
                  events:
                    - inbound_mail_received
              delivery_events:
                summary: Subscribe to all delivery events
                value:
                  target_url: https://example.com/webhooks/paubox
                  events:
                    - api_mail_log_delivered
                    - api_mail_log_temporary_failure
                    - api_mail_log_permanent_failure
                    - api_mail_log_opened
                  signing_key: whsec_abc123
      responses:
        '201':
          description: Webhook endpoint created
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Webhook created!
                  data:
                    $ref: '#/components/schemas/WebhookEndpoint'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
  /webhook_endpoints/{id}:
    get:
      tags:
        - Webhooks
      summary: Get a webhook endpoint
      description: Retrieve a webhook endpoint by ID, including its target URL, subscribed events, active status, and signing key.
      operationId: getWebhookEndpoint
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Webhook endpoint ID
      responses:
        '200':
          description: Webhook endpoint details
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/WebhookEndpoint'
        '404':
          description: Webhook endpoint not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
    patch:
      tags:
        - Webhooks
      summary: Update a webhook endpoint
      description: Update a webhook endpoint's target URL or subscribed events, or disable it by setting active to false. Only the fields you send are changed.
      operationId: updateWebhookEndpoint
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Webhook endpoint ID
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateWebhookEndpointRequest'
            examples:
              disable:
                summary: Disable an endpoint
                value:
                  active: false
              change_events:
                summary: Update subscribed events
                value:
                  events:
                    - inbound_mail_received
                    - api_mail_log_delivered
      responses:
        '200':
          description: Webhook endpoint updated
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Webhook updated!
                  data:
                    $ref: '#/components/schemas/WebhookEndpoint'
        '404':
          description: Webhook endpoint not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
    delete:
      tags:
        - Webhooks
      summary: Delete a webhook endpoint
      description: Delete a webhook endpoint by ID. Paubox stops sending event notifications to its target URL.
      operationId: deleteWebhookEndpoint
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: Webhook endpoint ID
      responses:
        '200':
          description: Webhook endpoint deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: Webhook deleted!
                  data:
                    $ref: '#/components/schemas/WebhookEndpoint'
        '404':
          description: Webhook endpoint not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - PauboxToken: []
components:
  schemas:
    SingleSendRequest:
      required:
        - data
      type: object
      properties:
        data:
          $ref: '#/components/schemas/SingleSendRequest_data'
    BulkSendRequest:
      required:
        - data
      type: object
      properties:
        data:
          $ref: '#/components/schemas/BulkSendRequest_data'
    Message:
      required:
        - content
        - headers
        - recipients
      type: object
      properties:
        recipients:
          minItems: 1
          type: array
          items:
            type: string
            description: >-
              Email address, optionally with display name (e.g., "J. Smith
              <jsmith@host.com>").
        bcc:
          type: array
          items:
            type: string
        cc:
          type: array
          items:
            type: string
        headers:
          $ref: '#/components/schemas/MessageHeaders'
        allowNonTLS:
          type: boolean
          description: >
            Allow delivery over non-TLS rather than converting to a Secure
            Portal message. Not HIPAA compliant if the message contains PHI.
          default: false
        forceSecureNotification:
          type: boolean
          description: >
            Force delivery as a Paubox Secure Message; recipient gets a pickup
            notification with a link.
          default: false
        content:
          $ref: '#/components/schemas/MessageContent'
        attachments:
          type: array
          items:
            $ref: '#/components/schemas/Attachment'
    MessageHeaders:
      required:
        - from
        - subject
      type: object
      properties:
        subject:
          type: string
        from:
          type: string
          description: Must match the verified domain of your API key.
        reply-to:
          type: string
          description: >-
            Reply-to address; must match a verified domain if different from
            from.
        List-Unsubscribe:
          type: string
          description: >
            Insert a List-Unsubscribe header (mailto and/or http). See RFC
            guidance for syntax.
        List-Unsubscribe-Post:
          type: string
          description: Used in conjunction with List-Unsubscribe header.
        x-custom-header:
          type: string
          description: >-
            Example custom header; any custom header may be added with an X-
            prefix.
        additionalProperties:
          type: string
          description: Any additional X- prefixed custom header values.
    MessageContent:
      type: object
      properties:
        text/plain:
          type: string
          description: Plain text message body. Required if text/html is not provided.
        text/html:
          type: string
          description: >
            HTML message body. May be HTML-escaped, base64-encoded, or a valid
            unescaped string. CSS in <style> tags will be rendered inline.
      oneOf:
        - required:
            - text/plain
        - required:
            - text/html
    Attachment:
      required:
        - content
        - contentType
        - fileName
      type: object
      properties:
        fileName:
          type: string
        contentType:
          type: string
          description: Valid MIME type, e.g., application/pdf.
        content:
          type: string
          description: Base64-encoded file contents.
    SingleSendResponse:
      type: object
      properties:
        sourceTrackingId:
          type: string
          description: Identifier for tracking the message source.
        customHeaders:
          type: object
          additionalProperties:
            type: string
        data:
          type: string
          example: Service OK
    BulkSendResponse:
      type: object
      properties:
        messages:
          type: array
          items:
            $ref: '#/components/schemas/BulkSendResponse_messages'
    ErrorResponse:
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ErrorResponse_errors'
    MessageReceiptResponse:
      required:
        - data
        - sourceTrackingId
      type: object
      properties:
        sourceTrackingId:
          type: string
          description: The tracking ID for the message
          example: 6e1cf9a4-7bde-4834-8200-ed424b50c8a7
        data:
          $ref: '#/components/schemas/MessageReceiptResponse_data'
    MessageReceiptErrorResponse:
      required:
        - errors
        - sourceTrackingId
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ErrorResponse_errors'
        sourceTrackingId:
          type: string
          description: The tracking ID for the message
          example: 6e1cf9a4-7bde-4834-8d200-ed424b50c8a7
    MessageDelivery:
      required:
        - recipient
        - status
      type: object
      properties:
        recipient:
          type: string
          description: The recipient email address
          example: recipient@host.com
        status:
          $ref: '#/components/schemas/DeliveryStatus'
    DeliveryStatus:
      required:
        - deliveryStatus
      type: object
      properties:
        deliveryStatus:
          type: string
          description: The delivery status of the message
          example: delivered
          enum:
            - processing
            - TLS not offered, sending via Secure Portal
            - soft bounced
            - soft bounced - mailbox full
            - hard bounced
            - Internal error. Please check back later.
            - delivered
            - delivered via secure portal
        deliveryTime:
          type: string
          description: The time when the message was delivered (if applicable)
          example: Mon, 23 Apr 2018 13:27:34 -0700
        openedStatus:
          type: string
          description: Whether the message was opened (single recipient only)
          example: opened
          enum:
            - opened
            - not opened
        openedTime:
          type: string
          description: The time when the message was first opened (single recipient only)
          example: Mon, 23 Apr 2018 13:27:51 -0700
    ClickData:
      required:
        - click_count
        - target_url
      type: object
      properties:
        click_count:
          type: integer
          description: Number of clicks on this specific link
          example: 1
        target_url:
          type: string
          description: The URL that was clicked
          example: amazon.com
    DynamicTemplateResponse:
      type: object
      properties:
        id:
          type: string
          description: Template ID
          example: template_123
        name:
          type: string
          description: Template name
          example: welcome_template
        body:
          type: string
          description: Template content (Handlebars)
          example: Hello {{name}}, welcome to our service!
        created_at:
          type: string
          description: Template creation timestamp
          format: date-time
        updated_at:
          type: string
          description: Template last update timestamp
          format: date-time
    DynamicTemplateListResponse:
      type: object
      properties:
        templates:
          type: array
          items:
            $ref: '#/components/schemas/DynamicTemplateResponse'
    TemplatedMessageRequest:
      required:
        - data
      type: object
      properties:
        data:
          $ref: '#/components/schemas/TemplatedMessageRequest_data'
    TemplatedMessage:
      required:
        - headers
        - recipients
      type: object
      properties:
        recipients:
          minItems: 1
          type: array
          items:
            type: string
            description: >-
              Email address, optionally with display name (e.g., "J. Smith
              <jsmith@host.com>").
        bcc:
          type: array
          items:
            type: string
        cc:
          type: array
          items:
            type: string
        headers:
          $ref: '#/components/schemas/TemplatedMessageHeaders'
        allowNonTLS:
          type: boolean
          description: >
            Allow delivery over non-TLS rather than converting to a Secure
            Portal message. Not HIPAA compliant if the message contains PHI.
          default: false
        forceSecureNotification:
          type: boolean
          description: >
            Force delivery as a Paubox Secure Message; recipient gets a pickup
            notification with a link.
          default: false
        attachments:
          type: array
          items:
            $ref: '#/components/schemas/Attachment'
    TemplatedMessageHeaders:
      required:
        - from
        - subject
      type: object
      properties:
        subject:
          type: string
          description: Message subject (can include template variables)
        from:
          type: string
          description: Must match the verified domain of your API key.
        reply-to:
          type: string
          description: >-
            Reply-to address; must match a verified domain if different from
            from.
        List-Unsubscribe:
          type: string
          description: >
            Insert a List-Unsubscribe header (mailto and/or http). See RFC
            guidance for syntax.
        List-Unsubscribe-Post:
          type: string
          description: Used in conjunction with List-Unsubscribe header.
        additionalProperties:
          type: string
          description: Any additional custom header values.
    dynamic_templates_body:
      required:
        - data[body]
        - data[name]
      type: object
      properties:
        data[name]:
          type: string
          description: Name for the template
          example: welcome_template
        data[body]:
          type: string
          description: Handlebars template file (.hbs)
          format: binary
    inline_response_200:
      type: object
      properties:
        message:
          type: string
          example: Template deleted successfully
    dynamic_templates_id_body:
      type: object
      properties:
        data[name]:
          type: string
          description: Updated name for the template
          example: updated_welcome_template
        data[body]:
          type: string
          description: Updated Handlebars template file (.hbs)
          format: binary
    SingleSendRequest_data:
      required:
        - message
      type: object
      properties:
        message:
          $ref: '#/components/schemas/Message'
        override_open_tracking:
          type: boolean
          description: Set to true to enable open tracking for this message.
        override_link_tracking:
          type: boolean
          description: >-
            Set to true to enable click tracking for this message (up to 1000
            links).
        unsubscribe_url:
          type: string
          description: URL to redirect unsubscribe requests for unsubscribe tracking.
          format: uri
    BulkSendRequest_data:
      required:
        - messages
      type: object
      properties:
        messages:
          type: array
          description: Recommended 50 or fewer per request.
          items:
            $ref: '#/components/schemas/Message'
    BulkSendResponse_messages:
      type: object
      properties:
        sourceTrackingId:
          type: string
        customHeaders:
          type: object
          additionalProperties:
            type: string
        data:
          type: string
          example: Service OK
    ErrorResponse_errors:
      type: object
      properties:
        code:
          type: integer
        title:
          type: string
        details:
          type: string
    MessageReceiptResponse_data_message:
      required:
        - id
        - message_deliveries
      type: object
      properties:
        id:
          type: string
          description: The message ID
          example: <f4a9b518-439c-497d-b87f-dfc9cc19194b@authorized_domain.com>
        message_deliveries:
          type: array
          items:
            $ref: '#/components/schemas/MessageDelivery'
        total_opens:
          type: integer
          description: Total number of opens (single recipient only)
          example: 1
        distinct_opens:
          type: integer
          description: Number of distinct opens (single recipient only)
          example: 1
        total_click_count:
          type: integer
          description: Total number of clicks (single recipient only)
          example: 2
        clicks_per_link:
          type: array
          description: Click tracking data per link (single recipient only)
          items:
            $ref: '#/components/schemas/ClickData'
        unsubscribed:
          type: boolean
          description: Whether the recipient has unsubscribed (single recipient only)
          example: false
    MessageReceiptResponse_data:
      required:
        - message
      type: object
      properties:
        message:
          $ref: '#/components/schemas/MessageReceiptResponse_data_message'
    TemplatedMessageRequest_data:
      required:
        - message
        - template_name
        - template_values
      type: object
      properties:
        template_name:
          type: string
          description: The name of the template to use (must match exactly)
          example: detailed_test
        template_values:
          type: string
          description: JSON-formatted string containing template variable values
          example: >-
            { "name": "Howard",
            "conditional":"true","items":["one","two","three"] }
        message:
          $ref: '#/components/schemas/TemplatedMessage'
    ScheduleSendRequest:
      required:
        - data
      type: object
      properties:
        data:
          type: object
          required:
            - message
            - scheduled_at
          properties:
            message:
              $ref: '#/components/schemas/Message'
            scheduled_at:
              type: string
              format: date-time
              description: ISO 8601 UTC datetime. Must be in the future and within 30 days.
              example: "2025-12-25T15:00:00Z"
    ScheduleSendResponse:
      type: object
      properties:
        sourceTrackingId:
          type: string
          example: 3d38ab13-0af8-4028-bd45-52e882e0d584
        scheduledAt:
          type: string
          format: date-time
          example: "2025-12-25T15:00:00Z"
        state:
          type: string
          example: pending
          enum:
            - pending
            - processing
            - sent
            - cancelled
            - failed
        data:
          type: string
          example: Service OK
    ScheduledMessageStatus:
      type: object
      properties:
        sourceTrackingId:
          type: string
          example: 3d38ab13-0af8-4028-bd45-52e882e0d584
        scheduledAt:
          type: string
          format: date-time
        state:
          type: string
          enum:
            - pending
            - processing
            - sent
            - cancelled
            - failed
        messageId:
          type: integer
        sentAt:
          type: string
          format: date-time
          nullable: true
        cancelledAt:
          type: string
          format: date-time
          nullable: true
        errorMessage:
          type: string
          nullable: true
    RescheduleRequest:
      required:
        - scheduled_at
      type: object
      properties:
        scheduled_at:
          type: string
          format: date-time
          description: New send time. Must be in the future and within 30 days.
          example: "2025-12-26T10:00:00Z"
    RescheduleResponse:
      type: object
      properties:
        sourceTrackingId:
          type: string
        scheduledAt:
          type: string
          format: date-time
        data:
          type: string
          example: Rescheduled
    CancelScheduledResponse:
      type: object
      properties:
        sourceTrackingId:
          type: string
        state:
          type: string
          example: cancelled
        data:
          type: string
          example: Cancelled
    CreateReceivingDomainRequest:
      type: object
      properties:
        slug:
          type: string
          description: >
            Custom subdomain slug. The full domain will be `<slug>.inbound.paubox.email`.
            If omitted, an auto-generated slug is assigned.
          example: support
    ReceivingDomain:
      type: object
      properties:
        id:
          type: integer
          example: 1
        domain:
          type: string
          example: support.inbound.paubox.email
        state:
          type: string
          enum:
            - active
            - pending
          example: active
        dns_records:
          type: array
          items:
            $ref: '#/components/schemas/DnsRecord'
    DnsRecord:
      type: object
      properties:
        type:
          type: string
          example: MX
        name:
          type: string
          example: support.inbound.paubox.email
        value:
          type: string
          example: 10 mail.support.inbound.paubox.email
    ReceivingDomainListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ReceivingDomain'
    ReceivingDomainResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/ReceivingDomain'
    CreateMailboxRequest:
      required:
        - name
        - password
      type: object
      properties:
        name:
          type: string
          description: >
            Local part of the mailbox address. The full address will be
            `<name>@<domain>`.
          example: support
        password:
          type: string
          description: Mailbox password.
          example: SecurePass123!
        quota_bytes:
          type: integer
          description: Storage quota in bytes. Omit for no quota.
          example: 1073741824
    Mailbox:
      type: object
      properties:
        id:
          type: integer
          example: 1
        name:
          type: string
          example: support
        email_address:
          type: string
          example: support@company.inbound.paubox.email
        quota_bytes:
          type: integer
          nullable: true
          example: 1073741824
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    MailboxListResponse:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Mailbox'
    MailboxResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/Mailbox'
    EmailAddress:
      type: object
      properties:
        address:
          type: string
          example: sender@example.com
        name:
          type: string
          nullable: true
          example: Jane Doe
    ReceivedEmail:
      type: object
      properties:
        email_id:
          type: string
          example: eaaaaab
        from:
          type: array
          items:
            $ref: '#/components/schemas/EmailAddress'
        to:
          type: array
          items:
            $ref: '#/components/schemas/EmailAddress'
        subject:
          type: string
          example: Patient records request
        received_at:
          type: string
          format: date-time
          example: "2026-09-03T14:22:00Z"
        has_attachment:
          type: boolean
          example: false
        size:
          type: integer
          example: 3845
        spam:
          type: boolean
          example: false
        domain:
          type: string
          example: company.inbound.paubox.email
    ReceivedEmailDetail:
      type: object
      properties:
        email_id:
          type: string
          example: eaaaaab
        from:
          type: array
          items:
            $ref: '#/components/schemas/EmailAddress'
        to:
          type: array
          items:
            $ref: '#/components/schemas/EmailAddress'
        subject:
          type: string
        received_at:
          type: string
          format: date-time
        body_text:
          type: string
        body_html:
          type: string
        has_attachment:
          type: boolean
        size:
          type: integer
        spam:
          type: boolean
        domain:
          type: string
        attachments:
          type: array
          items:
            type: object
            properties:
              blob_id:
                type: string
              filename:
                type: string
              content_type:
                type: string
              size:
                type: integer
    ReceivedEmailListResponse:
      type: object
      properties:
        object:
          type: string
          example: list
        data:
          type: array
          items:
            $ref: '#/components/schemas/ReceivedEmail'
        has_more:
          type: boolean
          example: false
    ReceivedEmailResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/ReceivedEmailDetail'
    ReceivedAttachment:
      type: object
      properties:
        filename:
          type: string
          nullable: true
        content_type:
          type: string
          nullable: true
        size:
          type: integer
          nullable: true
        content_id:
          type: string
          nullable: true
        blob_id:
          type: string
          nullable: true
    WebhookEndpoint:
      type: object
      properties:
        id:
          type: integer
          example: 42
        target_url:
          type: string
          example: https://example.com/webhooks/paubox
        events:
          type: array
          items:
            type: string
            enum:
              - api_mail_log_delivered
              - api_mail_log_opened
              - api_mail_log_temporary_failure
              - api_mail_log_permanent_failure
              - inbound_mail_received
          example:
            - inbound_mail_received
            - api_mail_log_delivered
        active:
          type: boolean
          example: true
        signing_key:
          type: string
          nullable: true
          example: whsec_abc123
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    CreateWebhookEndpointRequest:
      required:
        - target_url
        - events
      type: object
      properties:
        target_url:
          type: string
          description: HTTPS URL to receive webhook deliveries. Must not point to a private or internal address.
          example: https://example.com/webhooks/paubox
        events:
          type: array
          description: Event types to subscribe to.
          items:
            type: string
            enum:
              - api_mail_log_delivered
              - api_mail_log_opened
              - api_mail_log_temporary_failure
              - api_mail_log_permanent_failure
              - inbound_mail_received
        signing_key:
          type: string
          description: Included as `x-webhook-signing-key` header on deliveries for verification.
        api_key:
          type: string
          description: Included as `x-api-key` header on deliveries.
        active:
          type: boolean
          description: Whether the endpoint is active. Defaults to `true`.
          default: true
    UpdateWebhookEndpointRequest:
      type: object
      properties:
        target_url:
          type: string
          description: New HTTPS URL.
        events:
          type: array
          items:
            type: string
            enum:
              - api_mail_log_delivered
              - api_mail_log_opened
              - api_mail_log_temporary_failure
              - api_mail_log_permanent_failure
              - inbound_mail_received
        active:
          type: boolean
        api_key:
          type: string
  securitySchemes:
    PauboxToken:
      type: http
      scheme: bearer
      description: >
        Paubox API uses Bearer token authentication in the Authorization header.


        Format: `Authorization: Bearer YOUR_API_KEY_HERE`


        Example: `Authorization: Bearer
        9e5b092b632445b8f570c62ae54f30fda1044305`


        The legacy format `Authorization: Token token=YOUR_API_KEY_HERE` is also
        supported.
