components:
  schemas:
    APIKey:
      properties:
        id:
          description: The API key ID for the sub-account.
          type: integer
        key:
          description: API key for the sub-account.
          type: string
      type: object
    AsyncSendResponse:
      properties:
        queued_at:
          description: 'ISO 8601 timestamp when the request was queued for processing.

            '
          format: date-time
          type: string
        request_id:
          description: 'Unique identifier for tracking this async request.

            Will be included in all webhook events for this request.

            '
          type: string
      required:
      - request_id
      - queued_at
      type: object
    Attachment:
      properties:
        content:
          description: the attachment data, encoded in base64
          type: string
        content_id:
          description: 'A unique identifier for this attachment. When set, the attachment
            is embedded

            inline in the message body (Content-Disposition: inline) instead of offered
            as a

            downloadable attachment, and can be referenced from HTML content via a
            `cid:` URI,

            e.g. `<img src="cid:logo123">` refers to an attachment with `content_id:
            logo123`

            (RFC 2392). Must be unique across all attachments in the request.

            '
          maxLength: 255
          pattern: ^[\x21-\x3B\x3D\x3F-\x7E]{1,255}$
          type: string
        filename:
          description: the name of the attachment file
          type: string
        type:
          description: the MIME type of the attachment
          type: string
      required:
      - content
      - filename
      type: object
    CheckDomainBody:
      properties:
        dkim_settings:
          description: 'Each item may include DKIM domain, selector and private key.
            Up to 10 items are allowed.

            The absence or presence of these fields affects how DKIM settings are
            validated:

            1. If dkim_domain, dkim_selector, and dkim_private_key are all present,
            verify using the provided domain, selector, and key.

            2. If dkim_domain and dkim_selector are present, use the stored private
            key for the given domain and selector.

            3. If only dkim_domain is present, use all stored keys for the given domain.

            4. If none are present, use all stored keys for the domain provided in
            the `domain` field of the request.

            5. If dkim_private_key is present, dkim_selector must be present.

            6. If dkim_selector is present and dkim_domain is not, the domain will
            be taken from the `domain` field of the request.

            '
          items:
            $ref: '#/components/schemas/DkimSetting'
          maxItems: 10
          type: array
        domain:
          description: 'Domain used for sending emails. If dkim_settings are not provided,
            or dkim_settings are provided with no dkim_domain,

            the stored dkim settings for this domain will be used.

            '
          type: string
        sender_id:
          description: 'Used exclusively for [Domain Lockdown](https://support.mailchannels.com/hc/en-us/articles/16918954360845-Secure-your-domain-name-against-spoofing-with-Domain-Lockdown)
            verification.

            If you''re not using `senderid` to associate your domain with your account,
            you can disregard this field.

            The corresponding value is included in the X-MailChannels-SenderId header
            of emails sent via MailChannels.

            '
          type: string
      required:
      - domain
      type: object
    CheckDomainResult:
      properties:
        check_results:
          $ref: '#/components/schemas/CheckResults'
        references:
          description: Link to SPF, Domain Lockdown or DKIM references, displayed
            if any verdict is not passed.
          items:
            type: string
          type: array
      type: object
    CheckResults:
      properties:
        dkim:
          items:
            $ref: '#/components/schemas/DkimResult'
          type: array
        domain_lockdown:
          $ref: '#/components/schemas/LockdownResult'
        sender_domain:
          $ref: '#/components/schemas/SenderDomainResult'
        spf:
          $ref: '#/components/schemas/SpfResult'
      type: object
    ContentItem:
      properties:
        template_type:
          description: The template type of the content
          enum:
          - mustache
          type: string
        type:
          description: The mime type of the content you are including in your email
          type: string
        value:
          description: The actual content of the specified mime type that you are
            including in the message
          type: string
      required:
      - type
      - value
      type: object
    CustomTrackingDomain:
      properties:
        created_at:
          description: ISO 8601 timestamp when the domain was registered
          format: date-time
          type: string
        hostname:
          description: The registered domain hostname
          type: string
        name:
          description: The label for this custom tracking domain
          type: string
        scope:
          description: The event type this domain handles
          enum:
          - click
          - open
          - unsubscribe
          type: string
        status:
          description: Current status of the custom tracking domain
          enum:
          - active
          - disabled
          type: string
      required:
      - name
      - hostname
      - scope
      - status
      - created_at
      type: object
    CustomTrackingDomainListResponse:
      properties:
        custom_tracking_domains:
          description: List of custom tracking domains matching the filter criteria
          items:
            $ref: '#/components/schemas/CustomTrackingDomain'
          type: array
        total:
          description: Total number of custom tracking domains
          type: integer
      required:
      - custom_tracking_domains
      - total
      type: object
    DKIMDnsRecord:
      description: 'Suggested DNS record for the DKIM key

        '
      nullable: true
      properties:
        name:
          type: string
        type:
          example: TXT
          type: string
        value:
          type: string
      required:
      - name
      - type
      - value
      type: object
    DKIMKeyInfo:
      properties:
        algorithm:
          description: 'Algorithm used for the key pair

            '
          type: string
        created_at:
          description: 'Timestamp when the key pair was created

            '
          format: date-time
          nullable: true
          type: string
        dkim_dns_records:
          description: 'Suggested DNS records for the DKIM key

            '
          items:
            $ref: '#/components/schemas/DKIMDnsRecord'
          type: array
        domain:
          description: 'Domain associated with the key pair

            '
          type: string
        gracePeriodExpiresAt:
          description: 'UTC timestamp after which you can no longer use the rotated
            key for signing

            '
          format: date-time
          nullable: true
          type: string
        key_length:
          description: 'Key length in bits

            '
          type: integer
        public_key:
          type: string
        retiresAt:
          description: 'UTC timestamp when a rotated key pair is retired

            '
          format: date-time
          nullable: true
          type: string
        selector:
          description: 'Selector assigned to the key pair

            '
          type: string
        status:
          enum:
          - active
          - retired
          - revoked
          - rotated
          type: string
        status_modified_at:
          description: 'Timestamp when the key was last modified

            '
          format: date-time
          nullable: true
          type: string
      required:
      - domain
      - selector
      - public_key
      - status
      - algorithm
      type: object
    DKIMKeyList:
      properties:
        keys:
          description: 'List of keys matching the filter.

            Empty if no keys match the filter.

            '
          items:
            $ref: '#/components/schemas/DKIMKeyInfo'
          type: array
      required:
      - keys
      type: object
    DKIMKeyPairCreateRequest:
      properties:
        algorithm:
          default: rsa
          description: 'Algorithm used for the new key pair

            Currently, only RSA is supported.

            '
          enum:
          - rsa
          type: string
        key_length:
          default: 2048
          description: 'Key length in bits.

            For RSA, must be a multiple of 1024. Common values: 1024 or 2048.

            Defaults to 2048 bits.

            '
          maximum: 4096
          minimum: 1024
          type: integer
        selector:
          description: 'Selector for the new key pair

            '
          maxLength: 63
          minLength: 1
          type: string
      required:
      - selector
      type: object
    DKIMKeyPairUpdateRequest:
      properties:
        status:
          description: 'New status of the DKIM key pair

            '
          enum:
          - revoked
          - retired
          - rotated
          type: string
      required:
      - status
      type: object
    DKIMKeyRotateRequest:
      properties:
        new_key:
          $ref: '#/components/schemas/NewKey'
      required:
      - new_key
      type: object
    DKIMKeyRotateResponse:
      properties:
        new_key:
          $ref: '#/components/schemas/DKIMKeyInfo'
        rotated_key:
          $ref: '#/components/schemas/DKIMKeyInfo'
      required:
      - new_key
      - rotated_key
      type: object
    DkimResult:
      properties:
        dkim_domain:
          type: string
        dkim_key_status:
          description: 'The human readable status of the DKIM key used for verification.

            This field is only present if the DKIM check was performed using a DKIM
            key managed by MailChannels.

            If a DKIM key is present in the request, this field will not be included.

            '
          type: string
        dkim_selector:
          type: string
        reason:
          description: A human-readable explanation of DKIM check.
          type: string
        verdict:
          enum:
          - passed
          - failed
          type: string
      type: object
    DkimSetting:
      description: 'Domain, selector and private key for DKIM signing.

        '
      properties:
        dkim_domain:
          description: 'The Signing Domain Identifier; the d= field in a DKIM-Signature
            header

            '
          type: string
        dkim_private_key:
          description: 'Encoded in Base64.

            '
          type: string
        dkim_selector:
          type: string
      type: object
    DnsSetupRequired:
      properties:
        instructions:
          description: Human-readable guidance for the DNS records that must be in
            place before retrying.
          type: string
        token:
          description: UUID v4 nonce; also the TXT record value to set. Present only
            when TXT ownership verification is pending.
          example: 550e8400-e29b-41d4-a716-446655440000
          type: string
        txt_record_name:
          description: Fully-qualified DNS TXT record name to add. Present only when
            TXT ownership verification is pending.
          example: _mailchannels-verify.click.example.com
          type: string
        txt_record_value:
          description: Value for the DNS TXT record (same as token). Present only
            when TXT ownership verification is pending.
          example: 550e8400-e29b-41d4-a716-446655440000
          type: string
      type: object
    EmailAddress:
      properties:
        email:
          type: string
        name:
          description: "Display name in raw text, e.g. John Doe, \u5F20\u4E09"
          type: string
      required:
      - email
      type: object
    ErrorResponse:
      properties:
        errors:
          description: 'This is an array error objects that provide machine and human
            readable descriptions of the errors.

            '
          items:
            type: string
          type: array
      type: object
    Key:
      properties:
        id:
          type: string
        key:
          description: The public key used to verify webhook signatures
          type: string
      required:
      - id
      - key
      type: object
    Limit:
      properties:
        sends:
          type: integer
      required:
      - sends
      type: object
    LimitInput:
      properties:
        sends:
          minimum: 0
          type: integer
      required:
      - sends
      type: object
    LimitUpdateResult:
      properties:
        limit:
          $ref: '#/components/schemas/Limit'
      type: object
    LockdownResult:
      properties:
        reason:
          description: 'A human-readable explanation of Domain Lockdown check.

            '
          type: string
        verdict:
          enum:
          - passed
          - failed
          type: string
      type: object
    MailSendBody:
      properties:
        attachments:
          items:
            $ref: '#/components/schemas/Attachment'
          maxItems: 1000
          type: array
        campaign_id:
          description: 'The campaign identifier. If specified, this ID will be included
            in all relevant webhooks. It can be up to 48 UTF-8 characters long and
            must not contain spaces.

            '
          type: string
        content:
          items:
            $ref: '#/components/schemas/ContentItem'
          type: array
        dkim_domain:
          description: 'If set, you must also provide the matching dkim_selector.

            '
          type: string
        dkim_private_key:
          description: 'Encoded in Base64.

            If set, you must also provide the matching dkim_domain and dkim_selector.

            '
          type: string
        dkim_selector:
          description: 'If set without a matching dkim_domain, the domain will be
            taken from the `from` email address.

            '
          type: string
        envelope_from:
          $ref: '#/components/schemas/EmailAddress'
          description: 'Optional envelope sender address. If not set, the envelope
            sender defaults to the from.email field.

            Can be overridden per-personalization.

            Only the email portion is used; the name field is ignored.

            '
        from:
          $ref: '#/components/schemas/EmailAddress'
        headers:
          additionalProperties:
            type: string
          description: "A JSON object containing key-value pairs, where both keys\
            \ (header names) and values must be strings.\nThese pairs represent custom\
            \ headers to be substituted. Please note the following restrictions and\
            \ behavior:\n- Reserved headers: The following headers cannot be modified:\n\
            \  - Authentication-Results\n  - BCC\n  - CC\n  - Content-Transfer-Encoding\n\
            \  - Content-Type\n  - DKIM-Signature\n  - From\n  - Message-ID\n  - Received\n\
            \  - Reply-To\n  - Subject\n  - To\n- Header precedence: If a header is\
            \ defined in both the personalizations object and the root headers,\n\
            the value from personalizations will be used.\n- Case sensitivity: Headers\
            \ are treated as case-insensitive. If multiple headers differ only by\
            \ case,\nonly one will be used, with no guarantee of which one.\n"
          type: object
        personalizations:
          items:
            $ref: '#/components/schemas/Personalization'
          maxItems: 1000
          type: array
        reply_to:
          $ref: '#/components/schemas/EmailAddress'
        subject:
          type: string
        tracking_settings:
          description: 'Settings to adjust open and click tracking for the message.
            Please note that

            enabling tracking for your messages requires a subscription that supports
            open

            and click tracking.

            '
          properties:
            click_tracking:
              properties:
                custom_domain_name:
                  description: 'The name of a configured active click tracking domain.
                    When specified, click

                    tracking links will use this domain instead of the default MailChannels
                    domain.

                    The domain must be registered in your account and have an active
                    status.

                    '
                  maxLength: 64
                  pattern: ^[a-z0-9-]+$
                  type: string
                enable:
                  default: false
                  description: 'Setting to enable or disable click tracking for the
                    message.

                    This feature allows you to track when a recipient clicks a link
                    in your email.

                    '
                  type: boolean
              type: object
            open_tracking:
              properties:
                custom_domain_name:
                  description: 'The name of a configured active open tracking domain.
                    When specified, the open

                    tracking pixel will use this domain instead of the default MailChannels
                    domain.

                    The domain must be registered in your account and have an active
                    status.

                    '
                  maxLength: 64
                  pattern: ^[a-z0-9-]+$
                  type: string
                enable:
                  default: false
                  description: 'Setting to enable or disable open tracking for the
                    message.

                    This feature allows you to track when a recipient opens your email.

                    Please note that some email clients may not support open tracking.

                    '
                  type: boolean
              type: object
          type: object
        transactional:
          default: true
          description: "Mark these messages as transactional or non-transactional.\n\
            In order for a message to be marked as non-transactional,\nit must have\
            \ exactly one recipient per personalization,\nand it must be DKIM signed.\
            \ 400 Bad Request will be returned\nif there are more than one recipient\
            \ in any personalization for\nnon-transactional messages.\nIf a message\
            \ is marked as non-transactional, it changes the sending process as follows:\n\
            \  * List-Unsubscribe and List-Unsubscribe-Post headers will be added,\
            \ unless you supply your own List-Unsubscribe header, in which case yours\
            \ is used and neither is added.\n"
          nullable: true
          type: boolean
        unsubscribe_settings:
          description: 'Settings to customize the unsubscribe experience for the message.

            '
          properties:
            custom_domain_name:
              description: 'The name of a configured active unsubscribe tracking domain.
                When specified,

                unsubscribe links will use this domain instead of the default MailChannels
                domain.

                The domain must be registered in your account and have an active status.

                '
              maxLength: 64
              pattern: ^[a-z0-9-]+$
              type: string
          type: object
      required:
      - personalizations
      - from
      - subject
      - content
      type: object
    Message:
      properties:
        data:
          description: a string representation of a rendered message, one per personalization
            in the request
          items:
            type: string
          type: array
      type: object
    MetricsBucket:
      description: 'Represents a time-based bucket for aggregating metrics data.

        Each bucket corresponds to a specific time interval, with the `period_start`
        indicating the beginning of that interval.

        The `count` field represents the number of events or occurrences that fall
        within that time period.

        '
      properties:
        count:
          description: The number of events or occurrences aggregated within this
            time period.
          minimum: 0
          type: integer
        period_start:
          description: The starting date and time of the time period this bucket represents.
          format: date-time
          type: string
      required:
      - period_start
      - count
      type: object
    MetricsEngagement:
      properties:
        buckets:
          description: A series of metrics aggregations bucketed by time interval
            (e.g. hour, day)
          properties:
            click:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            click_tracking_delivered:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            open:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            open_tracking_delivered:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            unique_click:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            unique_click_tracking_delivered:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            unique_open:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            unique_open_tracking_delivered:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
          required:
          - open
          - open_tracking_delivered
          - click
          - click_tracking_delivered
          type: object
        click:
          description: 'Count of click events by recipients.

            '
          minimum: 0
          type: integer
        click_tracking_delivered:
          description: 'Count of recipients of delivered messages with HTML content
            that contains tracked click URLs,

            where click tracking is enabled in the send request.

            '
          minimum: 0
          type: integer
        end_time:
          description: 'The end of the time range for retrieving message engagement
            metrics (exclusive).

            '
          format: date-time
          type: string
        open:
          description: 'Count of open events by recipients.

            '
          minimum: 0
          type: integer
        open_tracking_delivered:
          description: 'Count of recipients of delivered messages with HTML content
            where open tracking was enabled

            in the send request.

            '
          minimum: 0
          type: integer
        start_time:
          description: 'The beginning of the time range for retrieving message engagement
            metrics (inclusive).

            '
          format: date-time
          type: string
        unique_click:
          description: 'Count of distinct messages that had at least one click event.
            Unlike `click`, each message

            is counted at most once regardless of how many links were clicked or how
            many times.

            Use this to compute click rates without exceeding 100%.

            '
          minimum: 0
          type: integer
        unique_click_tracking_delivered:
          description: 'Count of distinct messages delivered with click tracking enabled
            (message-level, not

            recipient-level). Use as the denominator when computing unique click rates.

            '
          minimum: 0
          type: integer
        unique_open:
          description: 'Count of distinct messages that had at least one open event.
            Unlike `open`, each message

            is counted at most once regardless of how many times its tracking pixel
            was fired.

            Use this to compute open rates without exceeding 100%.

            '
          minimum: 0
          type: integer
        unique_open_tracking_delivered:
          description: 'Count of distinct messages delivered with open tracking enabled
            (message-level, not

            recipient-level). Use as the denominator when computing unique open rates.

            '
          minimum: 0
          type: integer
      required:
      - open
      - open_tracking_delivered
      - click
      - click_tracking_delivered
      - buckets
      type: object
    MetricsPerformance:
      properties:
        bounced:
          description: 'Count of messages hard-bounced during the specified time range.

            '
          minimum: 0
          type: integer
        buckets:
          description: A series of metrics aggregations bucketed by time interval
            (e.g. hour, day)
          properties:
            bounced:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            complained:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            delivered:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            processed:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
          required:
          - delivered
          - bounced
          - complained
          - processed
          type: object
        complained:
          description: 'Count of messages complained during the specified time range.

            '
          minimum: 0
          type: integer
        delivered:
          description: 'Count of messages delivered during the specified time range.

            '
          minimum: 0
          type: integer
        end_time:
          description: The end of the time range for retrieving message performance
            metrics (exclusive).
          format: date-time
          type: string
        processed:
          description: 'Count of messages processed during the specified time range.

            '
          minimum: 0
          type: integer
        start_time:
          description: 'The beginning of the time range for retrieving message performance
            metrics (inclusive).

            '
          format: date-time
          type: string
      required:
      - delivered
      - bounced
      - complained
      - processed
      - buckets
      type: object
    MetricsRecipientBehaviour:
      properties:
        buckets:
          description: A series of metrics aggregations bucketed by time interval
            (e.g. hour, day)
          properties:
            unsubscribe_delivered:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            unsubscribed:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
          required:
          - unsubscribed
          - unsubscribe_delivered
          type: object
        end_time:
          description: 'The end of the time range for retrieving recipient behaviour
            metrics (exclusive).

            '
          format: date-time
          type: string
        start_time:
          description: 'The beginning of the time range for retrieving recipient behaviour
            metrics (inclusive).

            '
          format: date-time
          type: string
        unsubscribe_delivered:
          description: 'Count of recipients of delivered messages that include at
            least one of the unsubscribe link

            or unsubscribe headers. Since the unsubscribe feature requires exactly
            one recipient per message,

            this count also represents the total number of delivered messages.

            '
          minimum: 0
          type: integer
        unsubscribed:
          description: 'Count of unsubscribed events by recipients.

            '
          minimum: 0
          type: integer
      required:
      - unsubscribed
      - unsubscribe_delivered
      - buckets
      type: object
    MetricsSender:
      properties:
        bounced:
          minimum: 0
          type: integer
        delivered:
          minimum: 0
          type: integer
        dropped:
          minimum: 0
          type: integer
        name:
          maxLength: 255
          type: string
        processed:
          minimum: 0
          type: integer
      required:
      - name
      - processed
      - delivered
      - bounced
      - dropped
      type: object
    MetricsSenderResponse:
      properties:
        end_time:
          format: date-time
          type: string
        limit:
          type: integer
        offset:
          type: integer
        senders:
          items:
            $ref: '#/components/schemas/MetricsSender'
          type: array
        start_time:
          format: date-time
          type: string
        total:
          description: 'The total number of senders in this category that sent messages
            in the given time range.

            '
          type: integer
      required:
      - limit
      - offset
      - total
      - senders
      type: object
    MetricsVolume:
      properties:
        buckets:
          description: A series of metrics aggregations bucketed by time interval
            (e.g. hour, day)
          properties:
            delivered:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            dropped:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
            processed:
              items:
                $ref: '#/components/schemas/MetricsBucket'
              type: array
          required:
          - processed
          - delivered
          - dropped
          type: object
        delivered:
          description: 'Count of messages delivered during the specified time range.

            '
          minimum: 0
          type: integer
        dropped:
          description: 'Count of messages dropped during the specified time range.

            '
          minimum: 0
          type: integer
        end_time:
          description: 'The end of the time range for retrieving message volume metrics
            (exclusive).

            '
          format: date-time
          type: string
        processed:
          description: 'Count of messages processed during the specified time range.

            '
          minimum: 0
          type: integer
        start_time:
          description: 'The beginning of the time range for retrieving message volume
            metrics (inclusive).

            '
          format: date-time
          type: string
      required:
      - processed
      - delivered
      - dropped
      - buckets
      type: object
    NewKey:
      properties:
        selector:
          description: Selector for the new key pair
          maxLength: 63
          minLength: 1
          type: string
      required:
      - selector
      type: object
    PatchCustomTrackingDomainRequest:
      properties:
        name:
          description: New label for this custom tracking domain
          maxLength: 64
          pattern: ^[a-z0-9-]+$
          type: string
        status:
          description: "New status; active \u2194 disabled"
          enum:
          - active
          - disabled
          type: string
      type: object
    Personalization:
      properties:
        bcc:
          items:
            $ref: '#/components/schemas/EmailAddress'
          maxItems: 1000
          type: array
        cc:
          items:
            $ref: '#/components/schemas/EmailAddress'
          maxItems: 1000
          type: array
        dkim_domain:
          description: 'If set, you must also provide the matching dkim_selector.

            '
          type: string
        dkim_private_key:
          description: 'Encoded in Base64.

            If set, you must also provide the matching dkim_domain and dkim_selector.

            '
          type: string
        dkim_selector:
          description: 'If set without a matching dkim_domain, the domain will be
            taken from the `from` email address.

            '
          type: string
        dynamic_template_data:
          description: 'A JSON object containing key-value pairs of variables to set
            for template rendering.

            Keys must be strings, and values can be one of the following types:

            * string

            * boolean

            * number

            * list, whose values are all of permitted types

            * map, whose keys must be strings, and whose values are all of permitted
            types

            '
          type: object
        envelope_from:
          $ref: '#/components/schemas/EmailAddress'
          description: 'Optional envelope sender address. If set, overrides the root-level
            envelope_from and from.email for this personalization.

            Only the email portion is used; the name field is ignored.

            '
        from:
          $ref: '#/components/schemas/EmailAddress'
        headers:
          additionalProperties:
            type: string
          description: "A JSON object containing key-value pairs, where both keys\
            \ (header names) and values must be strings.\nThese pairs represent custom\
            \ headers to be substituted. Please note the following restrictions and\
            \ behavior:\n- Reserved headers: The following headers cannot be modified:\n\
            \  - Authentication-Results\n  - BCC\n  - CC\n  - Content-Transfer-Encoding\n\
            \  - Content-Type\n  - DKIM-Signature\n  - From\n  - Message-ID\n  - Received\n\
            \  - Reply-To\n  - Subject\n  - To\n- Header precedence: If a header is\
            \ defined in both the personalizations object and the root headers,\n\
            the value from personalizations will be used.\n- Case sensitivity: Headers\
            \ are treated as case-insensitive. If multiple headers differ only by\
            \ case,\nonly one will be used, with no guarantee of which one.\n"
          type: object
        reply_to:
          $ref: '#/components/schemas/EmailAddress'
        subject:
          type: string
        to:
          items:
            $ref: '#/components/schemas/EmailAddress'
          maxItems: 1000
          minItems: 1
          type: array
      required:
      - to
    PostCustomTrackingDomainRequest:
      properties:
        hostname:
          description: 'The hostname to register as a custom tracking domain (e.g.,
            click.example.com).

            The hostname must have a CNAME record pointing to `links.mailchannels.net`.

            '
          type: string
        name:
          description: A unique label used to select this domain at message send time
          maxLength: 64
          pattern: ^[a-z0-9-]+$
          type: string
        scope:
          description: The event type this domain handles
          enum:
          - click
          - open
          - unsubscribe
          type: string
      required:
      - name
      - hostname
      - scope
      type: object
    SMTPPassword:
      properties:
        enabled:
          description: Whether the SMTP password is enabled
          type: boolean
        id:
          description: The SMTP password ID for the sub-account
          type: integer
        smtp_password:
          description: SMTP password for the sub-account
          type: string
      type: object
    SendResult:
      properties:
        index:
          description: 'The index of the personalization in the request. Starts at
            0.

            '
          type: integer
        message_id:
          description: 'The Message ID is a unique identifier generated by the service.

            Each personalization has a distinct Message ID, which is also used in
            the `Message-Id` header and included in webhooks.

            '
          type: string
        reason:
          description: A human-readable explanation of the status.
          type: string
        status:
          description: 'The status of the message.

            Note that ''sent'' is a temporary status; the final status will be provided
            through webhooks, if configured.

            '
          enum:
          - sent
          - failed
          type: string
      type: object
    SendResults:
      properties:
        request_id:
          description: 'The Request ID is a unique identifier generated by the service
            to track the HTTP request.

            It will also be included in all webhooks for reference.

            '
          type: string
        results:
          description: 'A list of results for each message sent.

            '
          items:
            $ref: '#/components/schemas/SendResult'
          type: array
      type: object
    SenderDomainResult:
      description: 'These results are here to help avoid SDNF (Sender Domain Not Found)
        blocks.

        For messages not to get blocked by [SDNF](https://support.mailchannels.com/hc/en-us/articles/203155500-550-5-2-1-SDNF-Sender-Domain-Not-Found),

        we require either an MX or A record to exist for the sender domain.

        '
      properties:
        a:
          properties:
            reason:
              description: 'A human-readable explanation of A record check.

                '
              type: string
            verdict:
              enum:
              - passed
              - failed
              type: string
          type: object
        mx:
          properties:
            reason:
              description: 'A human-readable explanation of MX record check.

                '
              type: string
            verdict:
              enum:
              - passed
              - failed
              type: string
          type: object
        verdict:
          description: Overall verdict. Passed if either A or MX record check passed.
          enum:
          - passed
          - failed
          type: string
      type: object
    SpfResult:
      properties:
        reason:
          description: 'A human-readable explanation of SPF check.

            '
          type: string
        spfRecord:
          description: 'The SPF record that was used for the check.

            '
          type: string
        spfRecordError:
          description: 'Error message if the SPF record lookup failed.

            '
          type: string
        verdict:
          enum:
          - passed
          - failed
          - soft failed
          - temporary error
          - permanent error
          - neutral
          - none
          - unknown
          type: string
      type: object
    SubAccountData:
      properties:
        company_name:
          description: 'The name of the company associated with the sub-account.

            This name is used for display purposes only and does not affect the functionality
            of the sub-account.

            The length must be between 3 and 128 characters.

            '
          type: string
        handle:
          description: 'A unique name for the sub-account to be created.

            The length must be between 3 and 128 characters, and it may contain only
            lowercase letters and numbers.

            If not provided, a random handle will be generated.

            '
          type: string
      required:
      - company_name
      type: object
    SubAccountDetails:
      properties:
        company_name:
          type: string
        enabled:
          type: boolean
        handle:
          type: string
      required:
      - handle
      - enabled
      type: object
    SuppressionEntry:
      properties:
        notes:
          maxLength: 1024
          nullable: true
          type: string
        recipient:
          maxLength: 255
          type: string
        suppression_types:
          items:
            enum:
            - transactional
            - non-transactional
            type: string
          type: array
      required:
      - recipient
      type: object
    SuppressionEntryResponse:
      properties:
        created_at:
          format: date-time
          type: string
        notes:
          maxLength: 1024
          nullable: true
          type: string
        recipient:
          maxLength: 255
          type: string
        sender:
          nullable: true
          type: string
        source:
          enum:
          - api
          - unsubscribe_link
          - list_unsubscribe
          - hard_bounce
          - spam_complaint
          type: string
        suppression_types:
          items:
            enum:
            - transactional
            - non-transactional
            type: string
          type: array
      required:
      - recipient
      type: object
    SuppressionListInput:
      properties:
        add_to_sub_accounts:
          default: false
          description: 'If true, the parent account creates suppression entries for
            all associated sub-accounts.

            This field is only applicable to parent accounts.

            Sub-accounts cannot create entries for other sub-accounts.

            '
          type: boolean
        suppression_entries:
          description: The total number of suppression entries to create, for the
            parent and/or its sub-accounts, must not exceed 1000.
          items:
            $ref: '#/components/schemas/SuppressionEntry'
          type: array
      required:
      - suppression_entries
      type: object
    SuppressionListResponse:
      properties:
        suppression_list:
          items:
            $ref: '#/components/schemas/SuppressionEntryResponse'
          maxItems: 1000
          type: array
      required:
      - suppression_list
      type: object
    UsageStats:
      properties:
        monthly_limit:
          description: 'The effective monthly limit for the current billing period.
            A limit of zero means the account cannot send any

            messages. For sub-accounts with no explicit limit set (i.e., -1), the
            monthly limit for the parent account is

            returned.

            '
          example: 10000
          type: integer
        period_end_date:
          description: The end date of the current billing period (ISO 8601 format).
          example: '2025-04-11'
          format: date
          type: string
        period_start_date:
          description: The start date of the current billing period (ISO 8601 format).
          example: '2025-03-12'
          format: date
          type: string
        total_usage:
          description: The total usage for the current billing period.
          example: 5000
          format: int64
          type: integer
      required:
      - total_usage
      - monthly_limit
      type: object
    Webhook:
      properties:
        webhook:
          description: A customer's webhook that events will be sent to
          type: string
      required:
      - webhook
      type: object
    WebhookBatch:
      properties:
        batch_id:
          description: 'Unique identifier for the webhook batch

            '
          format: int64
          minimum: 0
          type: integer
        created_at:
          description: 'Timestamp of when the webhook batch was created

            '
          format: date-time
          type: string
        customer_handle:
          description: 'Customer handle associated with the webhook batch

            '
          maxLength: 255
          type: string
        duration:
          $ref: '#/components/schemas/WebhookBatchDuration'
        event_count:
          description: 'Number of events in the webhook batch

            '
          minimum: 0
          type: integer
        status:
          description: 'Status of the webhook batch.

            no_response: no response returned from the webhook endpoint.

            '
          enum:
          - 1xx_response
          - 2xx_response
          - 3xx_response
          - 4xx_response
          - 5xx_response
          - no_response
          type: string
        status_code:
          description: 'HTTP status code returned by the webhook endpoint

            '
          maximum: 599
          minimum: 100
          nullable: true
          type: integer
        webhook:
          description: Webhook endpoint to which events in the batch were posted
          type: string
      required:
      - batch_id
      - customer_handle
      - webhook
      - status
      - created_at
      - event_count
      type: object
    WebhookBatchDuration:
      description: 'Duration of the webhook batch.

        measured from the time the request was sent to the webhook endpoint until

        the response was received.

        '
      properties:
        unit:
          enum:
          - milliseconds
          type: string
        value:
          minimum: 0
          type: integer
      required:
      - value
      - unit
      type: object
    WebhookBatchResult:
      properties:
        webhook_batches:
          description: 'List of webhook batches matching the filter.

            Empty if no webhook batches match the filter.

            '
          items:
            $ref: '#/components/schemas/WebhookBatch'
          type: array
      required:
      - webhook_batches
      type: object
    WebhookResendResponse:
      properties:
        batch_id:
          description: 'Unique identifier for the webhook batch

            '
          format: int64
          minimum: 0
          type: integer
        created_at:
          description: Timestamp of when the webhook batch was created
          format: date-time
          type: string
        customer_handle:
          description: Customer handle associated with the webhook batch
          maxLength: 255
          type: string
        duration_in_ms:
          description: 'Duration of the webhook batch in milliseconds, measured from
            the time the request was sent to the webhook

            endpoint until the response was received. Null indicates that no response
            was returned from the webhook

            endpoint.

            '
          minimum: 0
          nullable: true
          type: integer
        event_count:
          description: Number of events in the webhook batch
          minimum: 0
          type: integer
        status_code:
          description: 'HTTP status code returned by the webhook endpoint.

            Valid values are 100-599. Null indicates that no response was returned
            from the webhook endpoint.

            '
          maximum: 599
          nullable: true
          type: integer
        webhook:
          description: Webhook URL to which events in the batch were posted
          type: string
      required:
      - batch_id
      - customer_handle
      - webhook
      - created_at
      - event_count
      type: object
    WebhookResponse:
      description: 'The HTTP response returned by the webhook, including status code
        and response body.

        A null value indicates no response was received.

        Possible reasons include timeouts, connection failures, or other network-related
        issues.

        '
      nullable: true
      properties:
        body:
          description: 'Response body from webhook.

            Returns an error if unprocessable or too large.

            '
          type: string
        status:
          description: 'HTTP status code returned by the webhook

            '
          example: 200
          type: integer
      required:
      - status
      type: object
    WebhookValidationRequestBody:
      properties:
        request_id:
          description: 'Optional identifier in the webhook payload.

            If not provided, a value will be automatically generated.

            '
          maxLength: 28
          type: string
      type: object
    WebhookValidationResult:
      properties:
        response:
          $ref: '#/components/schemas/WebhookResponse'
        result:
          description: 'Indicates whether the webhook responded with a 2xx HTTP status
            code

            '
          enum:
          - passed
          - failed
          type: string
        webhook:
          description: 'The webhook that was validated

            '
          type: string
      required:
      - result
      - webhook
      - response
      type: object
    WebhookValidationResults:
      properties:
        all_passed:
          description: 'Indicates whether all webhook validations passed

            '
          type: boolean
        results:
          description: 'Detailed results for each tested webhook, including whether
            it returned a 2xx status code,

            along with its response status code and body.

            '
          items:
            $ref: '#/components/schemas/WebhookValidationResult'
          type: array
      required:
      - all_passed
      - results
      type: object
info:
  contact:
    email: support@mailchannels.com
    name: MailChannels Corporation
  description: 'This is the API reference for Email API. Here, you''ll find more detailed
    information on every endpoint, including parameters, response formats, and error
    codes.

    '
  title: Email API
  version: 1.6.0
openapi: 3.0.0
paths:
  /check-domain:
    post:
      description: 'Validates a domain''s email authentication setup by retrieving
        its DKIM, SPF, and Domain Lockdown status.

        This endpoint checks whether the domain is properly configured for secure
        email delivery.

        '
      parameters:
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckDomainBody'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CheckDomainResult'
          description: Success.
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '403':
          description: User does not have access to this feature
      summary: DKIM, SPF & Domain Lockdown Check
      tags:
      - DKIM
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ DOMAIN } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"\
          Set MAILCHANNELS_API_KEY before running\");\nif (!DOMAIN) throw new Error(\"\
          Set DOMAIN (the sending domain, e.g. example.com)\");\n\nconst mailchannels\
          \ = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst { data, error } = await\
          \ mailchannels.domains.check(DOMAIN);\n\nif (error) {\n  console.error(\"\
          Check domain failed:\", error);\n  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\ndomain = os.environ.get(\"DOMAIN\")\nif not domain:\n  \
          \  sys.exit(\"Set DOMAIN (the sending domain, e.g. example.com)\")\n\n#\
          \ Check that DKIM, SPF, and Domain Lockdown records are configured correctly\n\
          # and have propagated.\nresponse = mailchannels.CheckDomain.check(domain)\n\
          \nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $domain  = getenv(''DOMAIN'') or exit("Error: DOMAIN is not set\n");


          $client = new Client(apiKey: $api_key);


          // Check that DKIM, SPF, and Domain Lockdown records are configured correctly

          // and have propagated.

          $response = $client->checkDomain->check($domain);


          print_r($response->toArray());'
  /custom-tracking-domains:
    get:
      description: 'Retrieve all custom tracking domains registered under your account.

        Optional filters include domain name, status, scope, limit and offset.

        '
      parameters:
      - description: Filter by custom tracking domain label
        in: query
        name: name
        required: false
        schema:
          type: string
      - description: Filter by status
        in: query
        name: status
        required: false
        schema:
          enum:
          - active
          - disabled
          type: string
      - description: Filter by scope
        in: query
        name: scope
        required: false
        schema:
          enum:
          - click
          - open
          - unsubscribe
          type: string
      - description: The maximum number of domains to return. The default is 100.
        in: query
        name: limit
        required: false
        schema:
          default: 100
          maximum: 1000
          minimum: 1
          type: integer
      - description: The number of domains to skip before returning results. The default
          is 0.
        in: query
        name: offset
        required: false
        schema:
          default: 0
          minimum: 0
          type: integer
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomTrackingDomainListResponse'
          description: Response with the list of custom tracking domains
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Invalid query parameter value
        '500':
          description: Internal server error
      summary: Retrieve Custom Tracking Domains
      tags:
      - Custom Tracking
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.domains.customTracking.list();\n\
          \nif (error) {\n  console.error(\"List custom tracking domains failed:\"\
          , error);\n  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY (parent\
          \ or sub-account) before running\")\n\n# Retrieve custom tracking domains\
          \ registered under the account.\nresponse = mailchannels.CustomTrackingDomains.list()\n\
          \nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");


          $client = new Client(apiKey: $api_key);


          // Retrieve custom tracking domains registered under the account.

          $response = $client->customTrackingDomains->list();


          print_r($response->toArray());'
    post:
      description: "Register a custom branded domain for click tracking, open tracking,\
        \ or unsubscribe handling.\nBy default, MailChannels uses shared domains for\
        \ these links. Using a custom domain improves\nbrand consistency by replacing\
        \ shared domains with your own (e.g., click.example.com).\nOnce registered,\
        \ select the domain at send time using its `name`.\n\nBefore registration\
        \ completes, two DNS records must be in place:\n1. A TXT record at `_mailchannels-verify.<hostname>`\
        \ containing the verification token\n   (returned in the 202 response).\n\
        2. A CNAME record at `<hostname>` pointing to `links.mailchannels.net`.\n"
      parameters:
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostCustomTrackingDomainRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomTrackingDomain'
          description: Domain verified and registered
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DnsSetupRequired'
          description: "Verification required \u2014 add the DNS TXT record and CNAME\
            \ record described in the response body, then retry"
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Invalid request body
        '403':
          description: No permission to register this domain
        '409':
          description: A domain with the same name already exists, or the hostname
            and scope combination is already registered
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DnsSetupRequired'
          description: 'DNS verification incomplete. Either the TXT ownership record
            has not propagated yet

            or the hostname CNAME does not point to the required target.

            Check the `instructions` field and retry once both records are in place.

            '
        '500':
          description: Internal Server Error
      summary: Register Custom Tracking Domain
      tags:
      - Custom Tracking
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ TRACKING_NAME, TRACKING_HOSTNAME } = process.env;\nif (!MAILCHANNELS_API_KEY)\
          \ throw new Error(\"Set MAILCHANNELS_API_KEY before running\");\nif (!TRACKING_NAME)\
          \ throw new Error(\"Set TRACKING_NAME (the label used to select this domain\
          \ at send time)\");\nif (!TRACKING_HOSTNAME) throw new Error(\"Set TRACKING_HOSTNAME\
          \ (e.g. click.example.com)\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \n// Register a branded hostname for click tracking, selected at send time\
          \ by name.\nconst { data, error } = await mailchannels.domains.customTracking.create(TRACKING_NAME,\
          \ TRACKING_HOSTNAME, \"click\");\n\nif (error) {\n  console.error(\"Register\
          \ custom tracking domain failed:\", error);\n  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\nname = os.environ.get(\"TRACKING_NAME\")\nhostname = os.environ.get(\"\
          TRACKING_HOSTNAME\")\nif not name:\n    sys.exit(\"Set TRACKING_NAME (the\
          \ label used to select this domain at send time)\")\nif not hostname:\n\
          \    sys.exit(\"Set TRACKING_HOSTNAME (e.g. click.example.com)\")\n\n# Register\
          \ a branded hostname for click tracking, selected at send time by name.\n\
          response = mailchannels.CustomTrackingDomains.create(name=name, hostname=hostname,\
          \ scope=\"click\")\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\nuse MailChannels\\Enum\\CustomTrackingScope;\n\n$api_key  = getenv('MAILCHANNELS_API_KEY')\
          \ or exit(\"Error: MAILCHANNELS_API_KEY is not set\\n\");\n$name     = getenv('TRACKING_NAME')\
          \ or exit(\"Error: TRACKING_NAME is not set\\n\");\n$hostname = getenv('TRACKING_HOSTNAME')\
          \ or exit(\"Error: TRACKING_HOSTNAME is not set\\n\");\n\n$client = new\
          \ Client(apiKey: $api_key);\n\n// Register a branded hostname for click\
          \ tracking, selected at send time by name.\n$response = $client->customTrackingDomains->create(\n\
          \    name: $name,\n    hostname: $hostname,\n    scope: CustomTrackingScope::Click,\n\
          );\n\nprint_r($response->toArray());"
  /custom-tracking-domains/{hostname}/{scope}:
    delete:
      description: 'Permanently delete an existing custom tracking domain for the
        given hostname and scope. The domain can be re-registered if needed.

        WARNING: Any tracking links or unsubscribe URLs in previously sent emails
        using this domain will stop working immediately.

        '
      parameters:
      - in: path
        name: hostname
        required: true
        schema:
          type: string
      - in: path
        name: scope
        required: true
        schema:
          enum:
          - click
          - open
          - unsubscribe
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '204':
          description: Custom tracking domain successfully deleted
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Invalid hostname or scope value
        '500':
          description: Internal server error
      summary: Delete Custom Tracking Domain
      tags:
      - Custom Tracking
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ TRACKING_HOSTNAME } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new\
          \ Error(\"Set MAILCHANNELS_API_KEY before running\");\nif (!TRACKING_HOSTNAME)\
          \ throw new Error(\"Set TRACKING_HOSTNAME (e.g. click.example.com)\");\n\
          \nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\n// Permanently\
          \ delete a custom tracking domain by hostname and scope.\nconst { success,\
          \ error } = await mailchannels.domains.customTracking.delete(TRACKING_HOSTNAME,\
          \ \"click\");\n\nif (!success) {\n  console.error(\"Delete custom tracking\
          \ domain failed:\", error);\n  process.exit(1);\n}\nconsole.log(\"Custom\
          \ tracking domain deleted\");"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\nhostname = os.environ.get(\"TRACKING_HOSTNAME\")\nif not\
          \ hostname:\n    sys.exit(\"Set TRACKING_HOSTNAME (e.g. click.example.com)\"\
          )\n\n# Permanently delete a custom tracking domain by hostname and scope.\n\
          response = mailchannels.CustomTrackingDomains.delete(hostname, \"click\"\
          )\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;

          use MailChannels\Enum\CustomTrackingScope;


          $api_key  = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $hostname = getenv(''TRACKING_HOSTNAME'') or exit("Error: TRACKING_HOSTNAME
          is not set\n");


          $client = new Client(apiKey: $api_key);


          // Permanently delete a custom tracking domain by hostname and scope.

          $response = $client->customTrackingDomains->delete($hostname, CustomTrackingScope::Click);


          echo "HTTP Status: " . $response->statusCode . "\n";'
    patch:
      description: 'Update an existing custom tracking domain by its hostname and
        scope.

        Supports updating the custom tracking domain''s name or toggling its active
        status.

        '
      parameters:
      - in: path
        name: hostname
        required: true
        schema:
          type: string
      - in: path
        name: scope
        required: true
        schema:
          enum:
          - click
          - open
          - unsubscribe
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchCustomTrackingDomainRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomTrackingDomain'
          description: Custom tracking domain updated
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DnsSetupRequired'
          description: "Re-activation requires DNS verification \u2014 add the TXT\
            \ record and CNAME record described in the response body, then retry"
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Invalid request body
        '403':
          description: No permission to activate this domain
        '404':
          description: Domain not found
        '409':
          description: Name already used by another domain
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DnsSetupRequired'
          description: 'DNS verification incomplete. Either the TXT ownership record
            has not propagated yet

            or the hostname CNAME does not point to the required target.

            Check the `instructions` field and retry once both records are in place.

            '
        '500':
          description: Internal server error
      summary: Update Custom Tracking Domain
      tags:
      - Custom Tracking
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ TRACKING_HOSTNAME } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new\
          \ Error(\"Set MAILCHANNELS_API_KEY before running\");\nif (!TRACKING_HOSTNAME)\
          \ throw new Error(\"Set TRACKING_HOSTNAME (e.g. click.example.com)\");\n\
          \nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\n// Disable\
          \ a custom tracking domain (identified by hostname and scope) without deleting\
          \ it.\nconst { data, error } = await mailchannels.domains.customTracking.update(TRACKING_HOSTNAME,\
          \ \"click\", {\n  status: \"disabled\",\n});\n\nif (error) {\n  console.error(\"\
          Update custom tracking domain failed:\", error);\n  process.exit(1);\n}\n\
          console.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\nhostname = os.environ.get(\"TRACKING_HOSTNAME\")\nif not\
          \ hostname:\n    sys.exit(\"Set TRACKING_HOSTNAME (e.g. click.example.com)\"\
          )\n\n# Disable a custom tracking domain (identified by hostname and scope)\
          \ without deleting it.\nresponse = mailchannels.CustomTrackingDomains.update(hostname,\
          \ \"click\", status=\"disabled\")\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\nuse MailChannels\\Enum\\CustomTrackingScope;\nuse MailChannels\\\
          Enum\\CustomTrackingStatus;\n\n$api_key  = getenv('MAILCHANNELS_API_KEY')\
          \ or exit(\"Error: MAILCHANNELS_API_KEY is not set\\n\");\n$hostname = getenv('TRACKING_HOSTNAME')\
          \ or exit(\"Error: TRACKING_HOSTNAME is not set\\n\");\n\n$client = new\
          \ Client(apiKey: $api_key);\n\n// Disable a custom tracking domain (identified\
          \ by hostname and scope) without deleting it.\n$response = $client->customTrackingDomains->update(\n\
          \    $hostname,\n    CustomTrackingScope::Click,\n    status: CustomTrackingStatus::Disabled,\n\
          );\n\nprint_r($response->toArray());"
  /domains/{domain}/dkim-keys:
    get:
      description: 'Search for DKIM keys by domain, with optional filters.

        If selector is provided, at most one key will be returned.

        '
      parameters:
      - in: path
        name: domain
        required: true
        schema:
          type: string
      - in: query
        name: selector
        required: false
        schema:
          maxLength: 63
          minLength: 1
          type: string
      - in: query
        name: status
        required: false
        schema:
          enum:
          - active
          - retired
          - revoked
          - rotated
          type: string
      - description: 'Number of keys to skip before returning results.

          The default is 0.

          '
        in: query
        name: offset
        required: false
        schema:
          default: 0
          minimum: 0
          type: integer
      - description: 'Maximum number of keys to return.

          The default is 10.

          '
        in: query
        name: limit
        required: false
        schema:
          default: 10
          maximum: 100
          minimum: 1
          type: integer
      - description: 'If true, includes the suggested DKIM DNS record for each returned
          key.

          Defaults to false.

          '
        in: query
        name: include_dns_record
        required: false
        schema:
          default: false
          type: boolean
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DKIMKeyList'
          description: Successfully retrieved DKIM keys
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '500':
          description: Internal Server Error
      summary: Retrieve DKIM Keys
      tags:
      - DKIM
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ DOMAIN } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"\
          Set MAILCHANNELS_API_KEY before running\");\nif (!DOMAIN) throw new Error(\"\
          Set DOMAIN (the sending domain, e.g. example.com)\");\n\nconst mailchannels\
          \ = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst { data, error } = await\
          \ mailchannels.domains.dkim.list(DOMAIN);\n\nif (error) {\n  console.error(\"\
          List DKIM keys failed:\", error);\n  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\ndomain = os.environ.get(\"DOMAIN\")\nif not domain:\n  \
          \  sys.exit(\"Set DOMAIN (the sending domain, e.g. example.com)\")\n\n#\
          \ List all MailChannels-managed DKIM keys for the domain.\nresponse = mailchannels.Dkim.list(domain)\n\
          \nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $domain  = getenv(''DOMAIN'') or exit("Error: DOMAIN is not set\n");


          $client = new Client(apiKey: $api_key);


          $response = $client->dkim->list($domain);


          print_r($response->toArray());'
    post:
      description: 'Create a DKIM key pair for a specified domain and selector using
        the specified algorithm and key length,

        for the current customer.

        '
      parameters:
      - in: path
        name: domain
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DKIMKeyPairCreateRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DKIMKeyInfo'
          description: Key pair created successfully
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '409':
          description: 'Key pair already created for domain, and selector

            '
        '500':
          description: Internal Server Error
      summary: Create DKIM Key Pair
      tags:
      - DKIM
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ DOMAIN, SELECTOR } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new\
          \ Error(\"Set MAILCHANNELS_API_KEY before running\");\nif (!DOMAIN) throw\
          \ new Error(\"Set DOMAIN (the sending domain, e.g. example.com)\");\nif\
          \ (!SELECTOR) throw new Error(\"Set SELECTOR (e.g. mc1)\");\n\nconst mailchannels\
          \ = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst { data, error } = await\
          \ mailchannels.domains.dkim.create(DOMAIN, {\n  selector: SELECTOR,\n  algorithm:\
          \ \"rsa\",\n  length: 2048,\n});\n\nif (error) {\n  console.error(\"Create\
          \ DKIM key failed:\", error);\n  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\ndomain = os.environ.get(\"DOMAIN\")\nselector = os.environ.get(\"\
          SELECTOR\")\nif not domain:\n    sys.exit(\"Set DOMAIN (the sending domain,\
          \ e.g. example.com)\")\nif not selector:\n    sys.exit(\"Set SELECTOR (e.g.\
          \ mc1)\")\n\n# Create a MailChannels-managed DKIM key pair. The response\
          \ includes the\n# public key and the DNS TXT record to publish.\nresponse\
          \ = mailchannels.Dkim.create(\n    domain,\n    selector=selector,\n   \
          \ algorithm=\"rsa\",\n    key_length=2048,\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\n\n$api_key  = getenv('MAILCHANNELS_API_KEY') or exit(\"Error: MAILCHANNELS_API_KEY\
          \ is not set\\n\");\n$domain   = getenv('DOMAIN') or exit(\"Error: DOMAIN\
          \ is not set\\n\");\n$selector = getenv('SELECTOR') or exit(\"Error: SELECTOR\
          \ is not set\\n\");\n\n$client = new Client(apiKey: $api_key);\n\n// Create\
          \ a MailChannels-managed DKIM key pair. The response includes the\n// public\
          \ key and the DNS TXT record to publish.\n$response = $client->dkim->create(\n\
          \    domain:    $domain,\n    selector:  $selector,\n    algorithm: 'rsa',\n\
          \    keyLength: 2048,\n);\n\nprint_r($response->toArray());"
  /domains/{domain}/dkim-keys/{selector}:
    patch:
      description: 'Update fields of an existing DKIM key pair for the specified domain
        and selector, for the current customer.

        Currently, only the status field can be updated.

        revoked: Indicates that the key is compromised and should not be used.

        retired: Indicates that the key has been rotated and is no longer in use.

        rotated: Indicates that the key is going through the rotation process. Only
        active key pairs can be

        updated to this status, and no new key pair is created. The rotated key can
        be used to sign emails for 3 days after

        the status update, and will automatically change to ''retired'' 2 weeks after
        update. For a smooth key transition,

        it is recommended to create and publish a new key pair before signing is disabled
        for the rotated key.

        '
      parameters:
      - in: path
        name: domain
        required: true
        schema:
          type: string
      - in: path
        name: selector
        required: true
        schema:
          maxLength: 63
          minLength: 1
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DKIMKeyPairUpdateRequest'
        required: true
      responses:
        '204':
          description: Key pair status updated successfully
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Status not supported
        '404':
          description: 'Specified key pair not found, or no active key for rotation

            This may also occur if the DKIM domain or selector path parameter is missing.

            '
        '500':
          description: Internal Server Error
      summary: Update DKIM Key Status
      tags:
      - DKIM
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ DOMAIN, SELECTOR } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new\
          \ Error(\"Set MAILCHANNELS_API_KEY before running\");\nif (!DOMAIN) throw\
          \ new Error(\"Set DOMAIN (the sending domain, e.g. example.com)\");\nif\
          \ (!SELECTOR) throw new Error(\"Set SELECTOR (the DKIM key selector to update)\"\
          );\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst\
          \ { success, error } = await mailchannels.domains.dkim.updateStatus(DOMAIN,\
          \ {\n  selector: SELECTOR,\n  status: \"retired\",\n});\n\nif (!success)\
          \ {\n  console.error(\"Update DKIM key status failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log({ success });"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\ndomain = os.environ.get(\"DOMAIN\")\nselector = os.environ.get(\"\
          SELECTOR\")\nif not domain:\n    sys.exit(\"Set DOMAIN (the sending domain,\
          \ e.g. example.com)\")\nif not selector:\n    sys.exit(\"Set SELECTOR (the\
          \ DKIM key selector to update)\")\n\nresponse = mailchannels.Dkim.update_status(domain,\
          \ selector, status=\"retired\")\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key  = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $domain   = getenv(''DOMAIN'') or exit("Error: DOMAIN is not set\n");

          $selector = getenv(''SELECTOR'') or exit("Error: SELECTOR is not set\n");


          $client = new Client(apiKey: $api_key);


          $response = $client->dkim->updateStatus($domain, $selector, ''retired'');


          echo "HTTP Status: " . $response->statusCode . "\n";'
  /domains/{domain}/dkim-keys/{selector}/rotate:
    post:
      description: Rotate an active DKIM key pair. Mark the original key as 'rotated',
        and create a new key pair with the required new key selector, reusing the
        same algorithm and key length. The rotated key remains valid for signing for
        a 3-day grace period, and is automatically changed to 'retired' 2 weeks after
        rotation. Publish the new key to its DNS TXT record before rotated key expires
        for signing as emails sent with an unpublished key will fail DKIM validation
        by receiving providers. After the grace period, only the new key is valid
        for signing if published.
      parameters:
      - in: path
        name: domain
        required: true
        schema:
          type: string
      - in: path
        name: selector
        required: true
        schema:
          maxLength: 63
          minLength: 1
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DKIMKeyRotateRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DKIMKeyRotateResponse'
          description: Key pair status updated and new key pair created successfully
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '404':
          description: Specified key pair not found
        '409':
          description: 'Key pair already created for domain, and provided new key
            selector.

            '
        '500':
          description: Internal Server Error
        '503':
          description: Temporarily unavailable for maintenance
          headers:
            Retry-After:
              description: 'Suggested wait time in seconds before retrying.

                '
              schema:
                example: '20'
                type: string
      summary: Rotate DKIM Key Pair
      tags:
      - DKIM
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ DOMAIN, CURRENT_SELECTOR, NEW_SELECTOR } = process.env;\nif (!MAILCHANNELS_API_KEY)\
          \ throw new Error(\"Set MAILCHANNELS_API_KEY before running\");\nif (!DOMAIN)\
          \ throw new Error(\"Set DOMAIN (the sending domain, e.g. example.com)\"\
          );\nif (!CURRENT_SELECTOR) throw new Error(\"Set CURRENT_SELECTOR (the active\
          \ key to rotate out)\");\nif (!NEW_SELECTOR) throw new Error(\"Set NEW_SELECTOR\
          \ (the selector for the new active key)\");\n\nconst mailchannels = new\
          \ MailChannels(MAILCHANNELS_API_KEY);\n\nconst { data, error } = await mailchannels.domains.dkim.rotate(DOMAIN,\
          \ CURRENT_SELECTOR, {\n  newKey: { selector: NEW_SELECTOR },\n});\n\nif\
          \ (error) {\n  console.error(\"Rotate DKIM key failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\ndomain = os.environ.get(\"DOMAIN\")\ncurrent_selector =\
          \ os.environ.get(\"CURRENT_SELECTOR\")\nnew_selector = os.environ.get(\"\
          NEW_SELECTOR\")\nif not domain:\n    sys.exit(\"Set DOMAIN (the sending\
          \ domain, e.g. example.com)\")\nif not current_selector:\n    sys.exit(\"\
          Set CURRENT_SELECTOR (the active key to rotate out)\")\nif not new_selector:\n\
          \    sys.exit(\"Set NEW_SELECTOR (the selector for the new active key)\"\
          )\n\nresponse = mailchannels.Dkim.rotate(\n    domain,\n    current_selector,\n\
          \    new_selector=new_selector,\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key          = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $domain           = getenv(''DOMAIN'') or exit("Error: DOMAIN is not set\n");

          $current_selector = getenv(''CURRENT_SELECTOR'') or exit("Error: CURRENT_SELECTOR
          is not set\n");

          $new_selector     = getenv(''NEW_SELECTOR'') or exit("Error: NEW_SELECTOR
          is not set\n");


          $client = new Client(apiKey: $api_key);


          $response = $client->dkim->rotate($domain, $current_selector, $new_selector);


          print_r($response->toArray());'
  /metrics/engagement:
    get:
      description: 'Retrieve engagement metrics for messages sent from your account,

        including counts of open and click events.

        Supports optional filters for time range, and campaign ID.

        '
      parameters:
      - description: 'The beginning of the time range for retrieving message engagement
          metrics (inclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ.

          Defaults to one month ago if not provided.

          '
        example: '2025-05-26'
        in: query
        name: start_time
        required: false
        schema:
          type: string
      - description: 'The end of the time range for retrieving message engagement
          metrics (exclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ.

          Defaults to the current time if not provided.

          '
        example: '2025-05-31T15:16:17Z'
        in: query
        name: end_time
        required: false
        schema:
          type: string
      - description: 'The ID of the campaign to filter metrics by.

          If not provided, metrics for all campaigns will be returned.

          '
        in: query
        name: campaign_id
        required: false
        schema:
          type: string
      - description: "The interval for aggregating metrics data. Allowed values:\n\
          \  - hour: Hourly breakdown\n  - day: Daily breakdown (default)\n  - week:\
          \ Weekly breakdown\n  - month: Monthly breakdown\n"
        in: query
        name: interval
        required: false
        schema:
          default: day
          enum:
          - hour
          - day
          - week
          - month
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetricsEngagement'
          description: 'Successfully retrieved engagement metrics

            '
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '500':
          description: Internal Server Error
      summary: Retrieve Engagement Metrics
      tags:
      - Metrics
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.metrics.engagement({\n  startTime:\
          \ \"2026-01-01T00:00:00Z\",\n  endTime: \"2026-01-31T23:59:59Z\",\n});\n\
          \nif (error) {\n  console.error(\"Get engagement metrics failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# Retrieve daily open and click counts for a single campaign.\n\
          response = mailchannels.Metrics.engagement(\n    start_time=\"2026-01-01T00:00:00Z\"\
          ,\n    end_time=\"2026-01-31T23:59:59Z\",\n    campaign_id=\"newsletter_jan_2026\"\
          ,\n    interval=\"day\",\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\n\n$api_key = getenv('MAILCHANNELS_API_KEY') or exit(\"Error: MAILCHANNELS_API_KEY\
          \ is not set\\n\");\n\n$client = new Client(apiKey: $api_key);\n\n// Retrieve\
          \ daily open and click counts for a single campaign.\n$response = $client->metrics->engagement(\n\
          \    startTime:  '2026-01-01T00:00:00Z',\n    endTime:    '2026-01-31T23:59:59Z',\n\
          \    campaignId: 'newsletter_jan_2026',\n    interval:   'day',\n);\n\n\
          print_r($response->toArray());"
  /metrics/performance:
    get:
      description: 'Retrieve performance metrics for messages sent from your account,

        including counts of processed, delivered, hard-bounced, and complained events.

        Supports optional filters for time range, and campaign ID.

        '
      parameters:
      - description: 'The beginning of the time range for retrieving message performance
          metrics (inclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ.

          Defaults to one month ago if not provided.

          '
        example: '2025-05-26'
        in: query
        name: start_time
        required: false
        schema:
          type: string
      - description: 'The end of the time range for retrieving message performance
          metrics (exclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ.

          Defaults to the current time if not provided.

          '
        example: '2025-05-31T15:16:17Z'
        in: query
        name: end_time
        required: false
        schema:
          type: string
      - description: 'The ID of the campaign to filter metrics by.

          If not provided, metrics for all campaigns will be returned.

          '
        in: query
        name: campaign_id
        required: false
        schema:
          type: string
      - description: "The interval for aggregating metrics data. Allowed values:\n\
          \  - hour: Hourly breakdown\n  - day: Daily breakdown (default)\n  - week:\
          \ Weekly breakdown\n  - month: Monthly breakdown\n"
        in: query
        name: interval
        required: false
        schema:
          default: day
          enum:
          - hour
          - day
          - week
          - month
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetricsPerformance'
          description: 'Successfully retrieved performance metrics

            '
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '500':
          description: Internal Server Error
      summary: Retrieve Performance Metrics
      tags:
      - Metrics
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.metrics.performance({\n  startTime:\
          \ \"2026-01-01T00:00:00Z\",\n});\n\nif (error) {\n  console.error(\"Get\
          \ performance metrics failed:\", error);\n  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# Retrieve processed, delivered, and bounced counts from\
          \ a chosen start time.\nresponse = mailchannels.Metrics.performance(\n \
          \   start_time=\"2026-01-01T00:00:00Z\",\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\n\n$api_key = getenv('MAILCHANNELS_API_KEY') or exit(\"Error: MAILCHANNELS_API_KEY\
          \ is not set\\n\");\n\n$client = new Client(apiKey: $api_key);\n\n// Retrieve\
          \ processed, delivered, and bounced counts from a chosen start time.\n$response\
          \ = $client->metrics->performance(\n    startTime: '2026-01-01T00:00:00Z',\n\
          );\n\nprint_r($response->toArray());"
  /metrics/recipient-behaviour:
    get:
      description: 'Retrieve recipient behaviour metrics for messages sent from your
        account,

        including counts of unsubscribed events.

        Supports optional filters for time range, and campaign ID.

        '
      parameters:
      - description: 'The beginning of the time range for retrieving recipient behaviour
          metrics (inclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ.

          Defaults to one month ago if not provided.

          '
        example: '2025-05-26'
        in: query
        name: start_time
        required: false
        schema:
          type: string
      - description: 'The end of the time range for retrieving recipient behaviour
          metrics (exclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ.

          Defaults to the current time if not provided.

          '
        example: '2025-05-31T15:16:17Z'
        in: query
        name: end_time
        required: false
        schema:
          type: string
      - description: 'The ID of the campaign to filter metrics by.

          If not provided, metrics for all campaigns will be returned.

          '
        in: query
        name: campaign_id
        required: false
        schema:
          type: string
      - description: "The interval for aggregating metrics data. Allowed values:\n\
          \  - hour: Hourly breakdown\n  - day: Daily breakdown (default)\n  - week:\
          \ Weekly breakdown\n  - month: Monthly breakdown\n"
        in: query
        name: interval
        required: false
        schema:
          default: day
          enum:
          - hour
          - day
          - week
          - month
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetricsRecipientBehaviour'
          description: 'Successfully retrieved recipient behaviour metrics

            '
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '500':
          description: Internal Server Error
      summary: Retrieve Recipient Behaviour Metrics
      tags:
      - Metrics
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.metrics.recipientBehaviour({\n\
          \  startTime: \"2026-01-01T00:00:00Z\",\n  endTime: \"2026-01-31T23:59:59Z\"\
          ,\n});\n\nif (error) {\n  console.error(\"Get recipient behaviour metrics\
          \ failed:\", error);\n  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# Retrieve weekly unsubscribe activity for a single campaign.\n\
          response = mailchannels.Metrics.recipient_behaviour(\n    campaign_id=\"\
          weekly_newsletter\",\n    interval=\"week\",\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\n\n$api_key = getenv('MAILCHANNELS_API_KEY') or exit(\"Error: MAILCHANNELS_API_KEY\
          \ is not set\\n\");\n\n$client = new Client(apiKey: $api_key);\n\n// Retrieve\
          \ weekly unsubscribe activity for a single campaign.\n$response = $client->metrics->recipientBehaviour(\n\
          \    campaignId: 'weekly_newsletter',\n    interval:   'week',\n);\n\nprint_r($response->toArray());"
  /metrics/senders/{sender_type}:
    get:
      description: 'Retrieves a list of senders, either sub-accounts or campaigns,
        with their associated message metrics.

        Sorted by total # of sent messages (processed + dropped)

        Supports optional filter for time range, and optional settings for limit,
        offset, and sort order.

        Note: senders without any messages in the given time range will not be included
        in the results.

        The default time range is from one month ago to now, and the default sort
        order is descending.

        '
      parameters:
      - in: path
        name: sender_type
        required: true
        schema:
          enum:
          - campaigns
          - sub-accounts
          type: string
      - description: 'The beginning of the time range for retrieving top senders metrics
          (inclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ

          Defaults to one month ago if not provided.

          '
        in: query
        name: start_time
        required: false
        schema:
          type: string
      - description: 'The end of the time range for retrieving top senders metrics
          (exclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ

          Defaults to the current time if not provided.

          '
        in: query
        name: end_time
        required: false
        schema:
          type: string
      - description: 'The maximum number of senders to return

          The default is 10.

          '
        in: query
        name: limit
        required: false
        schema:
          default: 10
          maximum: 1000
          minimum: 1
          type: integer
      - description: 'The number of senders to skip before returning results.

          '
        in: query
        name: offset
        required: false
        schema:
          default: 0
          minimum: 0
          type: integer
      - description: 'The order in which to sort the results, based on total messages
          (processed + dropped).

          '
        in: query
        name: sort_order
        required: false
        schema:
          default: desc
          enum:
          - asc
          - desc
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetricsSenderResponse'
          description: 'Successfully retrieved top senders metrics

            '
        '400':
          description: Invalid request
        '500':
          description: Internal server error
      summary: Retrieve Sender Metrics
      tags:
      - Metrics
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.metrics.senders(\"campaigns\"\
          , {\n  startTime: \"2026-01-01T00:00:00Z\",\n  endTime: \"2026-01-31T23:59:59Z\"\
          ,\n});\n\nif (error) {\n  console.error(\"Get senders metrics failed:\"\
          , error);\n  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# Retrieve the top 50 campaigns by total messages (processed\
          \ + dropped) for January 2026.\nresponse = mailchannels.Metrics.senders(\n\
          \    \"campaigns\",\n    start_time=\"2026-01-01T00:00:00Z\",\n    end_time=\"\
          2026-01-31T23:59:59Z\",\n    limit=50,\n    offset=0,\n    sort_order=\"\
          desc\",\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\n\n$api_key = getenv('MAILCHANNELS_API_KEY') or exit(\"Error: MAILCHANNELS_API_KEY\
          \ is not set\\n\");\n\n$client = new Client(apiKey: $api_key);\n\n// Retrieve\
          \ the top 50 campaigns by total messages (processed + dropped) for January\
          \ 2026.\n$response = $client->metrics->senders(\n    senderType: 'campaigns',\n\
          \    startTime:  '2026-01-01T00:00:00Z',\n    endTime:    '2026-01-31T23:59:59Z',\n\
          \    limit:      50,\n    offset:     0,\n    sortOrder:  'desc',\n);\n\n\
          print_r($response->toArray());"
  /metrics/volume:
    get:
      description: 'Retrieve volume metrics for messages sent from your account,

        including counts of processed, delivered and dropped events.

        Supports optional filters for time range and campaign ID.

        '
      parameters:
      - description: 'The beginning of the time range for retrieving message volume
          metrics (inclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ.

          Defaults to one month ago if not provided.

          '
        example: '2025-05-26'
        in: query
        name: start_time
        required: false
        schema:
          type: string
      - description: 'The end of the time range for retrieving message volume metrics
          (exclusive).

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ.

          Defaults to the current time if not provided.

          '
        example: '2025-05-31T15:16:17Z'
        in: query
        name: end_time
        required: false
        schema:
          type: string
      - description: 'The ID of the campaign to filter metrics by.

          If not provided, metrics for all campaigns will be returned.

          '
        in: query
        name: campaign_id
        required: false
        schema:
          type: string
      - description: "The interval for aggregating metrics data. Allowed values:\n\
          \  - hour: Hourly breakdown\n  - day: Daily breakdown (default)\n  - week:\
          \ Weekly breakdown\n  - month: Monthly breakdown\n"
        in: query
        name: interval
        required: false
        schema:
          default: day
          enum:
          - hour
          - day
          - week
          - month
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MetricsVolume'
          description: 'Successfully retrieved volume metrics

            '
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '500':
          description: Internal Server Error
      summary: Retrieve Volume Metrics
      tags:
      - Metrics
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.metrics.volume({\n  startTime:\
          \ \"2026-01-01T00:00:00Z\",\n  endTime: \"2026-01-07T23:59:59Z\",\n});\n\
          \nif (error) {\n  console.error(\"Get volume metrics failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# Retrieve processed, delivered, and dropped counts for\
          \ the first week of January 2026.\nresponse = mailchannels.Metrics.volume(\n\
          \    start_time=\"2026-01-01T00:00:00Z\",\n    end_time=\"2026-01-07T23:59:59Z\"\
          ,\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\n\n$api_key = getenv('MAILCHANNELS_API_KEY') or exit(\"Error: MAILCHANNELS_API_KEY\
          \ is not set\\n\");\n\n$client = new Client(apiKey: $api_key);\n\n// Retrieve\
          \ processed, delivered, and dropped counts for the first week of January\
          \ 2026.\n$response = $client->metrics->volume(\n    startTime: '2026-01-01T00:00:00Z',\n\
          \    endTime:   '2026-01-07T23:59:59Z',\n);\n\nprint_r($response->toArray());"
  /send:
    post:
      description: 'Sends an email message to one or more recipients.


        **Click Tracking Notes:**

        Only links (`<a>` tags) meeting all of the following conditions are processed
        for click tracking:

        - The URL is non-empty.

        - The URL starts with "http" or "https".

        - The link does not have a clicktracking attribute set to ''off''.

        '
      parameters:
      - description: 'When present and set to true, the message will not be sent.
          Instead, the fully rendered

          message is returned. This can be useful for testing.

          '
        in: query
        name: dry-run
        required: false
        schema:
          type: boolean
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MailSendBody'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
          description: Success. Returned if dry-run is present in the query
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SendResults'
          description: Success
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: User does not have access to this feature
        '413':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: 'Payload too large - The total message size should not exceed
            30MB.

            This includes the message itself, headers, and the combined size of any
            attachments.

            '
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal Server Error
        '502':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Gateway
      summary: Send an Email
      tags:
      - Send
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ FROM_EMAIL, TO_EMAIL } = process.env;\nif (!MAILCHANNELS_API_KEY) throw\
          \ new Error(\"Set MAILCHANNELS_API_KEY before running\");\nif (!FROM_EMAIL)\
          \ throw new Error(\"Set FROM_EMAIL (must be on a Domain-Lockdown-authorized\
          \ domain)\");\nif (!TO_EMAIL) throw new Error(\"Set TO_EMAIL\");\n\nconst\
          \ mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst { data,\
          \ error } = await mailchannels.emails.send({\n  from: { email: FROM_EMAIL,\
          \ name: \"Your Name\" },\n  to: { email: TO_EMAIL, name: \"Recipient\" },\n\
          \  subject: \"Hello from MailChannels\",\n  text: \"Hello! This is a plain-text\
          \ fallback for clients that don't render HTML.\",\n  html: \"<p>Hello,</p><p>This\
          \ is my first <strong>HTML</strong> email sent via the MailChannels Email\
          \ API.</p>\",\n});\n\nif (error) {\n  console.error(\"Send failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\nfrom_email = os.environ.get(\"FROM_EMAIL\")\nto_email =\
          \ os.environ.get(\"TO_EMAIL\")\nif not from_email:\n    sys.exit(\"Set FROM_EMAIL\
          \ (must be on a Domain-Lockdown-authorized domain)\")\nif not to_email:\n\
          \    sys.exit(\"Set TO_EMAIL\")\n\nresponse = mailchannels.Emails.send(\n\
          \    {\n        \"from\": {\"email\": from_email, \"name\": \"Your Name\"\
          },\n        \"to\": [{\"email\": to_email, \"name\": \"Recipient\"}],\n\
          \        \"subject\": \"Hello from MailChannels\",\n        \"text\": \"\
          Hello! This is a plain-text fallback for clients that don't render HTML.\"\
          ,\n        \"html\": (\n            \"<p>Hello,</p>\"\n            \"<p>This\
          \ is my first <strong>HTML</strong> email sent via the \"\n            '<a\
          \ href=\"https://www.mailchannels.com/email-api/\">MailChannels Email API</a>.</p>'\n\
          \        ),\n    }\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\n\n$api_key    = getenv('MAILCHANNELS_API_KEY') or exit(\"Error:\
          \ MAILCHANNELS_API_KEY is not set\\n\");\n$from_email = getenv('FROM_EMAIL')\
          \ or exit(\"Error: FROM_EMAIL is not set\\n\");\n$to_email   = getenv('TO_EMAIL')\
          \ or exit(\"Error: TO_EMAIL is not set\\n\");\n\n$client = new Client(apiKey:\
          \ $api_key);\n\n$response = $client->emails->send([\n    'from'    => ['email'\
          \ => $from_email, 'name' => 'Your Name'],\n    'to'      => ['email' =>\
          \ $to_email, 'name' => 'Recipient'],\n    'subject' => 'Hello from MailChannels',\n\
          \    'text'    => 'Hello! This is a plain-text fallback for clients that\
          \ don\\'t render HTML.',\n    'html'    => '<p>Hello,</p><p>This is my first\
          \ <strong>HTML</strong> email sent via the <a href=\"https://www.mailchannels.com/email-api/\"\
          >MailChannels Email API</a>.</p>',\n]);\n\nprint_r($response->toArray());"
  /send-async:
    post:
      description: 'Queues an email message for asynchronous processing and returns
        immediately with a request ID.


        The email will be processed in the background, and you''ll receive webhook
        events

        for all delivery status updates (e.g. dropped, processed, delivered, hard-bounced).

        These webhook events are identical to those sent for the synchronous /send
        endpoint.


        Use this endpoint when you need to send emails without waiting for processing
        to complete.

        This can improve your application''s response time, especially when sending
        to multiple recipients.

        '
      parameters:
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MailSendBody'
        required: true
      responses:
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AsyncSendResponse'
          description: Request accepted and queued for processing
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: User does not have access to this feature
        '413':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: 'Payload too large - The total message size should not exceed
            30MB.

            This includes the message itself, headers, and the combined size of any
            attachments.

            '
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Internal Server Error
      summary: Send an Email Asynchronously
      tags:
      - Send
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ FROM_EMAIL, TO_EMAIL } = process.env;\nif (!MAILCHANNELS_API_KEY) throw\
          \ new Error(\"Set MAILCHANNELS_API_KEY before running\");\nif (!FROM_EMAIL)\
          \ throw new Error(\"Set FROM_EMAIL (must be on a Domain-Lockdown-authorized\
          \ domain)\");\nif (!TO_EMAIL) throw new Error(\"Set TO_EMAIL\");\n\nconst\
          \ mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst { data,\
          \ error } = await mailchannels.emails.sendAsync({\n  from: { email: FROM_EMAIL,\
          \ name: \"Your Name\" },\n  to: { email: TO_EMAIL, name: \"Recipient\" },\n\
          \  subject: \"Hello from MailChannels\",\n  text: \"This message was queued\
          \ for async delivery. Status updates will arrive via webhook.\",\n});\n\n\
          if (error) {\n  console.error(\"Send failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\nfrom_email = os.environ.get(\"FROM_EMAIL\")\nto_email =\
          \ os.environ.get(\"TO_EMAIL\")\nif not from_email:\n    sys.exit(\"Set FROM_EMAIL\
          \ (must be on a Domain-Lockdown-authorized domain)\")\nif not to_email:\n\
          \    sys.exit(\"Set TO_EMAIL\")\n\n# Emails.queue posts to /tx/v1/send-async.\
          \ Delivery events are reported via webhooks.\nresponse = mailchannels.Emails.queue(\n\
          \    {\n        \"from\": {\"email\": from_email, \"name\": \"Your Name\"\
          },\n        \"to\": [{\"email\": to_email, \"name\": \"Recipient\"}],\n\
          \        \"subject\": \"Hello from MailChannels\",\n        \"text\": \"\
          This message was queued for async delivery. Status updates will arrive via\
          \ webhook.\",\n    }\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\n\n$api_key    = getenv('MAILCHANNELS_API_KEY') or exit(\"Error:\
          \ MAILCHANNELS_API_KEY is not set\\n\");\n$from_email = getenv('FROM_EMAIL')\
          \ or exit(\"Error: FROM_EMAIL is not set\\n\");\n$to_email   = getenv('TO_EMAIL')\
          \ or exit(\"Error: TO_EMAIL is not set\\n\");\n\n$client = new Client(apiKey:\
          \ $api_key);\n\n// emails->queue posts to /tx/v1/send-async. Delivery events\
          \ are reported via webhooks.\n$response = $client->emails->queue([\n   \
          \ 'from'    => ['email' => $from_email, 'name' => 'Your Name'],\n    'to'\
          \      => ['email' => $to_email, 'name' => 'Recipient'],\n    'subject'\
          \ => 'Hello from MailChannels',\n    'text'    => 'This message was queued\
          \ for async delivery. Status updates will arrive via webhook.',\n]);\n\n\
          print_r($response->toArray());"
  /sub-account:
    get:
      description: 'Retrieves all sub-accounts associated with the parent account.

        The response is paginated with a default limit of 1000 sub-accounts per page
        and an offset of 0.

        '
      parameters:
      - in: query
        name: limit
        required: false
        schema:
          default: 1000
          description: The maximum number of sub-accounts to return. The default is
            1000.
          maximum: 1000
          minimum: 1
          type: integer
      - in: query
        name: offset
        required: false
        schema:
          default: 0
          description: The number of sub-accounts to skip before returning results.
            The default is 0.
          minimum: 0
          type: integer
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/SubAccountDetails'
                maxItems: 1000
                type: array
          description: Successfully retrieved all sub-accounts associated with the
            parent account.
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request. The limit and/or offset query parameter are invalid.
        '500':
          description: An unexpected internal error occurred.
      summary: Retrieve Sub-accounts
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY\
          \ } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"Set PARENT_API_KEY\
          \ (a parent-account API key) before running\");\n\nconst mailchannels =\
          \ new MailChannels(PARENT_API_KEY);\n\nconst { data, error } = await mailchannels.subAccounts.list();\n\
          \nif (error) {\n  console.error(\"List sub-accounts failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nif not parent_api_key:\n    sys.exit(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\")\n\nmailchannels.api_key\
          \ = parent_api_key\n\n# Retrieve all sub-accounts for the parent account.\n\
          response = mailchannels.SubAccounts.list()\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->list();


          print_r($response->toArray());'
    post:
      description: 'Creates a new sub-account under the parent account.

        Each sub-account must have a unique handle composed solely of lowercase alphanumeric
        characters.

        If no handle is provided, a random handle will be generated.

        '
      parameters:
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubAccountData'
        description: The details of the sub-account to create.
        required: false
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubAccountDetails'
          description: The sub-account was successfully created.
        '400':
          description: Malformed request. The request body is invalid.
        '403':
          description: The operation is forbidden. The parent account does not have
            permission to create sub-accounts.
        '409':
          description: A sub-account with the specified name already exists.
        '500':
          description: An unexpected internal error occurred.
      summary: Create Sub-account
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ COMPANY_NAME, SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY)\
          \ throw new Error(\"Set PARENT_API_KEY (a parent-account API key) before\
          \ running\");\nif (!COMPANY_NAME) throw new Error(\"Set COMPANY_NAME (display\
          \ name for the sub-account)\");\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\
          \n// SUB_ACCOUNT_HANDLE is optional. If omitted, MailChannels generates\
          \ a random handle.\nconst { data, error } = await mailchannels.subAccounts.create(COMPANY_NAME,\
          \ SUB_ACCOUNT_HANDLE);\n\nif (error) {\n  console.error(\"Create sub-account\
          \ failed:\", error);\n  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\ncompany_name = os.environ.get(\"COMPANY_NAME\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not company_name:\n    sys.exit(\"Set COMPANY_NAME\
          \ (display name for the sub-account)\")\n\nmailchannels.api_key = parent_api_key\n\
          \n# SUB_ACCOUNT_HANDLE is optional. If omitted, MailChannels generates a\
          \ random handle.\nresponse = mailchannels.SubAccounts.create(\n    company_name=company_name,\n\
          \    handle=os.environ.get(\"SUB_ACCOUNT_HANDLE\"),\n)\n\nprint(response)"
      - label: PHP
        lang: php
        source: "<?php\n\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse MailChannels\\\
          Client;\n\n$parent_api_key = getenv('PARENT_API_KEY') or exit(\"Error: PARENT_API_KEY\
          \ is not set\\n\");\n$company_name   = getenv('COMPANY_NAME') or exit(\"\
          Error: COMPANY_NAME is not set\\n\");\n\n$client = new Client(apiKey: $parent_api_key);\n\
          \n// SUB_ACCOUNT_HANDLE is optional. If omitted, MailChannels generates\
          \ a random handle.\n$response = $client->subAccounts->create(\n    companyName:\
          \ $company_name,\n    handle:      getenv('SUB_ACCOUNT_HANDLE') ?: null,\n\
          );\n\nprint_r($response->toArray());"
  /sub-account/{handle}:
    delete:
      description: Deletes the sub-account identified by its handle.
      parameters:
      - description: Handle of sub-account to be deleted.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '204':
          description: The specified sub-account(s) were successfully deleted.
        '500':
          description: An unexpected internal error occurred.
      summary: Delete Sub-account
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account to delete)\"\
          );\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\nconst {\
          \ success, error } = await mailchannels.subAccounts.delete(SUB_ACCOUNT_HANDLE);\n\
          \nif (!success) {\n  console.error(\"Delete sub-account failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(`Sub-account ${SUB_ACCOUNT_HANDLE} deleted`);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account to delete)\")\n\nmailchannels.api_key = parent_api_key\n\
          \nresponse = mailchannels.SubAccounts.delete(handle)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->delete($sub_account_handle);


          echo "HTTP Status: " . $response->statusCode . "\n";'
  /sub-account/{handle}/activate:
    post:
      description: 'Activates a suspended sub-account identified by its handle, restoring
        its ability to send emails.

        '
      parameters:
      - description: Handle of sub-account to be activated.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '204':
          description: The specified sub-account is successfully activated.
        '403':
          description: The operation is forbidden. The parent account does not have
            permission to activate the sub-account.
        '404':
          description: The specified sub-account does not exist.
        '500':
          description: An unexpected internal error occurred.
      summary: Activate Sub-account
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account to activate)\"\
          );\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\nconst {\
          \ success, error } = await mailchannels.subAccounts.activate(SUB_ACCOUNT_HANDLE);\n\
          \nif (!success) {\n  console.error(\"Activate sub-account failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(`Sub-account ${SUB_ACCOUNT_HANDLE} activated`);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account to activate)\")\n\nmailchannels.api_key = parent_api_key\n\
          \nresponse = mailchannels.SubAccounts.activate(handle)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->activate($sub_account_handle);


          print_r($response->toArray());'
  /sub-account/{handle}/api-key:
    get:
      description: 'Retrieves details of all API keys associated with the specified
        sub-account.

        For security reasons, the full API key is **not** returned; only the key ID
        and a partially redacted version are provided.

        '
      parameters:
      - description: Handle of the sub-account to retrieve the API key for.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: query
        name: limit
        required: false
        schema:
          default: 100
          description: The maximum number of API keys to return. The default is 100.
          maximum: 1000
          minimum: 1
          type: integer
      - in: query
        name: offset
        required: false
        schema:
          default: 0
          description: The number of API keys to skip before returning results. The
            default is 0.
          minimum: 0
          type: integer
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/APIKey'
                maxItems: 1000
                type: array
          description: Successfully retrieved the API key for the specified sub-account.
        '404':
          description: The specified sub-account does not exist.
        '500':
          description: An unexpected internal error occurred.
      summary: Retrieve Sub-account API Keys
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account whose keys you\
          \ want to list)\");\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\
          \nconst { data, error } = await mailchannels.subAccounts.listApiKeys(SUB_ACCOUNT_HANDLE);\n\
          \nif (error) {\n  console.error(\"List sub-account API keys failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account whose keys you want to list)\")\n\nmailchannels.api_key\
          \ = parent_api_key\n\nresponse = mailchannels.SubAccounts.ApiKeys.list(handle)\n\
          \nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->apiKeys->list($sub_account_handle);


          print_r($response->toArray());'
    post:
      description: 'Creates a new API key for the specified sub-account.

        '
      parameters:
      - description: Handle of the sub-account to create API key for.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/APIKey'
          description: 'A new API key was successfully created for the specified sub-account.

            '
        '403':
          description: 'The operation is forbidden. You can''t create API keys for
            this sub-account.

            '
        '404':
          description: 'The specified sub-account does not exist.

            '
        '422':
          description: 'You have reached the limit of API keys you can create for
            this sub-account.

            '
        '500':
          description: 'An unexpected internal error occurred.

            '
      summary: Create Sub-account API Key
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account to create a\
          \ key for)\");\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\
          \nconst { data, error } = await mailchannels.subAccounts.createApiKey(SUB_ACCOUNT_HANDLE);\n\
          \nif (error) {\n  console.error(\"Create sub-account API key failed:\",\
          \ error);\n  process.exit(1);\n}\n// data.key is shown only once. Store\
          \ it securely.\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account to create a key for)\")\n\nmailchannels.api_key = parent_api_key\n\
          \nresponse = mailchannels.SubAccounts.ApiKeys.create(handle)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key      = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle  = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->apiKeys->create($sub_account_handle);


          print_r($response->toArray());'
  /sub-account/{handle}/api-key/{id}:
    delete:
      description: 'Deletes the API key identified by its ID for the specified sub-account.

        '
      parameters:
      - description: 'Handle of the sub-account for which the API key should be deleted.

          '
        in: path
        name: handle
        required: true
        schema:
          type: string
      - description: The ID of the API key to delete.
        in: path
        name: id
        required: true
        schema:
          type: integer
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '204':
          description: 'The API key was successfully deleted for the sub-account.

            '
        '400':
          description: 'Missing or invalid API key ID.

            '
        '500':
          description: 'An unexpected internal error occurred.

            '
      summary: Delete Sub-account API Key
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE, API_KEY_ID } = process.env;\nif (!PARENT_API_KEY)\
          \ throw new Error(\"Set PARENT_API_KEY (a parent-account API key) before\
          \ running\");\nif (!SUB_ACCOUNT_HANDLE) throw new Error(\"Set SUB_ACCOUNT_HANDLE\"\
          );\nif (!API_KEY_ID) throw new Error(\"Set API_KEY_ID (the ID of the key\
          \ to delete)\");\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\
          \nconst { success, error } = await mailchannels.subAccounts.deleteApiKey(\n\
          \  SUB_ACCOUNT_HANDLE,\n  Number(API_KEY_ID),\n);\n\nif (!success) {\n \
          \ console.error(\"Delete sub-account API key failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(`Deleted API key ${API_KEY_ID} for sub-account ${SUB_ACCOUNT_HANDLE}`);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nkey_id = os.environ.get(\"API_KEY_ID\")\nif not parent_api_key:\n   \
          \ sys.exit(\"Set PARENT_API_KEY (a parent-account API key) before running\"\
          )\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\")\nif not key_id:\n\
          \    sys.exit(\"Set API_KEY_ID (the id of the key to delete)\")\n\nmailchannels.api_key\
          \ = parent_api_key\n\nresponse = mailchannels.SubAccounts.ApiKeys.delete(handle,\
          \ key_id)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");

          $api_key_id         = getenv(''API_KEY_ID'') or exit("Error: API_KEY_ID
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->apiKeys->delete($sub_account_handle, $api_key_id);


          print_r($response->toArray());'
  /sub-account/{handle}/limit:
    delete:
      description: 'Deletes the limit for the specified sub-account.

        After a successful deletion, the specified sub-account will be

        limited to the parent account''s limit.

        '
      parameters:
      - description: Handle of the sub-account to delete limit for.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '204':
          description: The limit was successfully deleted for the sub-account.
        '500':
          description: An unexpected internal error occurred.
      summary: Delete Sub-account Limit
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account whose limit\
          \ you want to clear)\");\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\
          \nconst { success, error } = await mailchannels.subAccounts.deleteLimit(SUB_ACCOUNT_HANDLE);\n\
          \nif (!success) {\n  console.error(\"Delete sub-account limit failed:\"\
          , error);\n  process.exit(1);\n}\nconsole.log({ success });"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account whose limit you want to clear)\")\n\nmailchannels.api_key\
          \ = parent_api_key\n\nresponse = mailchannels.SubAccounts.Limits.delete(handle)\n\
          \nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->limits->delete($sub_account_handle);


          print_r($response->toArray());'
    get:
      description: 'Retrieves the limit of a specified sub-account.

        A value of -1 indicates that the sub-account inherits the parent account''s
        limit,

        allowing the sub-account to utilize any remaining capacity within the parent
        account''s allocation.

        '
      parameters:
      - description: Handle of the sub-account to retrieve the limit for.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Limit'
          description: Successfully retrieved the limit for the specified sub-account.
        '404':
          description: The specified sub-account does not exist.
        '500':
          description: An unexpected internal error occurred.
      summary: Retrieve Sub-account Limit
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account to read the\
          \ limit for)\");\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\
          \nconst { data, error } = await mailchannels.subAccounts.getLimit(SUB_ACCOUNT_HANDLE);\n\
          \nif (error) {\n  console.error(\"Get sub-account limit failed:\", error);\n\
          \  process.exit(1);\n}\n// A value of -1 means no explicit limit; the sub-account\
          \ shares the parent's allocation.\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account to read the limit for)\")\n\nmailchannels.api_key = parent_api_key\n\
          \n# A value of -1 means the sub-account has no explicit limit and is bounded\n\
          # only by the parent account's overall limit.\nresponse = mailchannels.SubAccounts.Limits.retrieve(handle)\n\
          \nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          // A value of -1 means the sub-account has no explicit limit and is bounded

          // only by the parent account''s overall limit.

          $response = $client->subAccounts->limits->retrieve($sub_account_handle);


          print_r($response->toArray());'
    put:
      description: 'Sets the limit for the specified sub-account.

        The minimum allowed sends is 0.

        '
      parameters:
      - description: Handle of the sub-account to set limit for.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LimitInput'
        description: The value the sub-account limit to set.
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LimitUpdateResult'
          description: The limit was successfully updated for the specified sub-account.
        '400':
          description: 'Missing or invalid limit value.

            '
        '404':
          description: The specified sub-account does not exist.
        '500':
          description: An unexpected internal error occurred.
      summary: Set Sub-account Limit
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE, SEND_LIMIT } = process.env;\nif (!PARENT_API_KEY)\
          \ throw new Error(\"Set PARENT_API_KEY (a parent-account API key) before\
          \ running\");\nif (!SUB_ACCOUNT_HANDLE) throw new Error(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account to set a limit on)\");\nif (!SEND_LIMIT) throw new Error(\"\
          Set SEND_LIMIT (maximum sends per billing period, integer >= 0)\");\n\n\
          const mailchannels = new MailChannels(PARENT_API_KEY);\n\nconst { success,\
          \ error } = await mailchannels.subAccounts.setLimit(SUB_ACCOUNT_HANDLE,\
          \ {\n  sends: Number(SEND_LIMIT),\n});\n\nif (!success) {\n  console.error(\"\
          Set sub-account limit failed:\", error);\n  process.exit(1);\n}\nconsole.log({\
          \ success });"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nsend_limit = os.environ.get(\"SEND_LIMIT\")\nif not parent_api_key:\n\
          \    sys.exit(\"Set PARENT_API_KEY (a parent-account API key) before running\"\
          )\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE (the sub-account\
          \ to set a limit on)\")\nif not send_limit:\n    sys.exit(\"Set SEND_LIMIT\
          \ (maximum sends per billing period, integer >= 0)\")\n\nmailchannels.api_key\
          \ = parent_api_key\n\nresponse = mailchannels.SubAccounts.Limits.set(handle,\
          \ sends=int(send_limit))\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");

          $send_limit         = getenv(''SEND_LIMIT'') or exit("Error: SEND_LIMIT
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->limits->set($sub_account_handle, sends:
          (int) $send_limit);


          print_r($response->toArray());'
  /sub-account/{handle}/smtp-password:
    get:
      description: 'Retrieves details of all SMTP passwords associated with the specified
        sub-account.

        For security, the full SMTP password is **not** returned; only the password
        ID and a partially redacted version are provided.

        '
      parameters:
      - description: Handle of the sub-account to retrieve the SMTP password for.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/SMTPPassword'
                type: array
          description: Successfully retrieved the SMTP password for the specified
            sub-account.
        '404':
          description: The specified sub-account does not exist.
        '500':
          description: An unexpected internal error occurred.
      summary: Retrieve Sub-account SMTP Passwords
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account whose SMTP passwords\
          \ you want to list)\");\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\
          \nconst { data, error } = await mailchannels.subAccounts.listSmtpPasswords(SUB_ACCOUNT_HANDLE);\n\
          \nif (error) {\n  console.error(\"List SMTP passwords failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account whose SMTP passwords you want to list)\")\n\nmailchannels.api_key\
          \ = parent_api_key\n\nresponse = mailchannels.SubAccounts.SmtpPasswords.list(handle)\n\
          \nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->smtpPasswords->list($sub_account_handle);


          print_r($response->toArray());'
    post:
      description: 'Creates a new SMTP password for the specified sub-account.

        '
      parameters:
      - description: Handle of the sub-account to create SMTP password for.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SMTPPassword'
          description: A new SMTP password was successfully created for the specified
            sub-account.
        '403':
          description: 'The operation is forbidden. You can''t create SMTP passwords
            for this sub-account.

            '
        '404':
          description: The specified sub-account does not exist.
        '422':
          description: 'You have reached the limit of SMTP passwords you can create
            for this sub-account.

            '
        '500':
          description: An unexpected internal error occurred.
      summary: Create Sub-account SMTP Password
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account to create an\
          \ SMTP password for)\");\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\
          \nconst { data, error } = await mailchannels.subAccounts.createSmtpPassword(SUB_ACCOUNT_HANDLE);\n\
          \nif (error) {\n  console.error(\"Create SMTP password failed:\", error);\n\
          \  process.exit(1);\n}\n// data.smtpPassword is shown only once. Store it\
          \ securely.\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account to create an SMTP password for)\")\n\nmailchannels.api_key\
          \ = parent_api_key\n\n# smtp_password is shown only once in the response.\
          \ Store it securely.\nresponse = mailchannels.SubAccounts.SmtpPasswords.create(handle)\n\
          \nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->smtpPasswords->create($sub_account_handle);


          // smtpPassword is shown only once. Store it securely.

          print_r($response->toArray());'
  /sub-account/{handle}/smtp-password/{id}:
    delete:
      description: 'Deletes the SMTP password identified by its ID for the specified
        sub-account.

        '
      parameters:
      - description: Handle of the sub-account for which the SMTP password should
          be deleted.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - description: The ID of the SMTP password to delete.
        in: path
        name: id
        required: true
        schema:
          type: integer
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '204':
          description: The specified SMTP password was successfully deleted for the
            sub-account.
        '400':
          description: Missing or invalid SMTP password ID.
        '500':
          description: An unexpected internal error occurred.
      summary: Delete Sub-account SMTP Password
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE, SMTP_PASSWORD_ID } = process.env;\nif (!PARENT_API_KEY)\
          \ throw new Error(\"Set PARENT_API_KEY (a parent-account API key) before\
          \ running\");\nif (!SUB_ACCOUNT_HANDLE) throw new Error(\"Set SUB_ACCOUNT_HANDLE\"\
          );\nif (!SMTP_PASSWORD_ID) throw new Error(\"Set SMTP_PASSWORD_ID (the ID\
          \ of the password to delete)\");\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\
          \nconst { success, error } = await mailchannels.subAccounts.deleteSmtpPassword(\n\
          \  SUB_ACCOUNT_HANDLE,\n  Number(SMTP_PASSWORD_ID),\n);\n\nif (!success)\
          \ {\n  console.error(\"Delete SMTP password failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(`Deleted SMTP password ${SMTP_PASSWORD_ID} for sub-account\
          \ ${SUB_ACCOUNT_HANDLE}`);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\npassword_id = os.environ.get(\"SMTP_PASSWORD_ID\")\nif not parent_api_key:\n\
          \    sys.exit(\"Set PARENT_API_KEY (a parent-account API key) before running\"\
          )\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\")\nif not password_id:\n\
          \    sys.exit(\"Set SMTP_PASSWORD_ID (the ID of the password to delete)\"\
          )\n\nmailchannels.api_key = parent_api_key\n\nresponse = mailchannels.SubAccounts.SmtpPasswords.delete(handle,\
          \ password_id)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");

          $smtp_password_id   = getenv(''SMTP_PASSWORD_ID'') or exit("Error: SMTP_PASSWORD_ID
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->smtpPasswords->delete($sub_account_handle,
          (int) $smtp_password_id);


          echo "HTTP Status: " . $response->statusCode . "\n";'
  /sub-account/{handle}/suspend:
    post:
      description: 'Suspends the sub-account identified by its handle.

        This action disables the account, preventing it from sending any emails until
        it is reactivated.

        '
      parameters:
      - description: Handle of sub-account to be suspended.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '204':
          description: The specified sub-account is successfully suspended.
        '404':
          description: The specified sub-account does not exist.
        '500':
          description: An unexpected internal error occurred.
      summary: Suspend Sub-account
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account to suspend)\"\
          );\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\nconst {\
          \ success, error } = await mailchannels.subAccounts.suspend(SUB_ACCOUNT_HANDLE);\n\
          \nif (!success) {\n  console.error(\"Suspend sub-account failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(`Sub-account ${SUB_ACCOUNT_HANDLE} suspended`);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account to suspend)\")\n\nmailchannels.api_key = parent_api_key\n\
          \nresponse = mailchannels.SubAccounts.suspend(handle)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->suspend($sub_account_handle);


          echo "HTTP Status: " . $response->statusCode . "\n";'
  /sub-account/{handle}/usage:
    get:
      description: Retrieves usage statistics for the specified sub-account during
        the current billing period.
      parameters:
      - description: Handle of the sub-account to query usage stats for.
        in: path
        name: handle
        required: true
        schema:
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UsageStats'
          description: Successfully returned the usage stats.
        '404':
          description: Sub-account not found
        '500':
          description: Internal Server Error
      summary: Retrieve Sub-account Usage Stats
      tags:
      - Sub-accounts
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { PARENT_API_KEY,\
          \ SUB_ACCOUNT_HANDLE } = process.env;\nif (!PARENT_API_KEY) throw new Error(\"\
          Set PARENT_API_KEY (a parent-account API key) before running\");\nif (!SUB_ACCOUNT_HANDLE)\
          \ throw new Error(\"Set SUB_ACCOUNT_HANDLE (the sub-account to query)\"\
          );\n\nconst mailchannels = new MailChannels(PARENT_API_KEY);\n\nconst {\
          \ data, error } = await mailchannels.subAccounts.getUsage(SUB_ACCOUNT_HANDLE);\n\
          \nif (error) {\n  console.error(\"Get sub-account usage failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nparent_api_key =\
          \ os.environ.get(\"PARENT_API_KEY\")\nhandle = os.environ.get(\"SUB_ACCOUNT_HANDLE\"\
          )\nif not parent_api_key:\n    sys.exit(\"Set PARENT_API_KEY (a parent-account\
          \ API key) before running\")\nif not handle:\n    sys.exit(\"Set SUB_ACCOUNT_HANDLE\
          \ (the sub-account to query)\")\n\nmailchannels.api_key = parent_api_key\n\
          \nresponse = mailchannels.SubAccounts.retrieve_usage(handle)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $parent_api_key     = getenv(''PARENT_API_KEY'') or exit("Error: PARENT_API_KEY
          is not set\n");

          $sub_account_handle = getenv(''SUB_ACCOUNT_HANDLE'') or exit("Error: SUB_ACCOUNT_HANDLE
          is not set\n");


          $client = new Client(apiKey: $parent_api_key);


          $response = $client->subAccounts->retrieveUsage($sub_account_handle);


          print_r($response->toArray());'
  /suppression-list:
    get:
      description: 'Retrieve suppression entries associated with the specified account.

        Supports filtering by recipient, source and creation date range.

        The response is paginated, with a default limit of 1000 entries per page and
        an offset of 0.

        '
      parameters:
      - in: query
        name: recipient
        required: false
        schema:
          maxLength: 255
          type: string
      - in: query
        name: source
        required: false
        schema:
          enum:
          - api
          - unsubscribe_link
          - list_unsubscribe
          - hard_bounce
          - spam_complaint
          type: string
      - description: 'The date and/or time before which the suppression entries were
          created.

          Format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ

          '
        in: query
        name: created_before
        required: false
        schema:
          type: string
      - description: 'The date and/or time after which the suppression entries were
          created.

          Format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ

          '
        in: query
        name: created_after
        required: false
        schema:
          type: string
      - description: 'The maximum number of suppression entries to return. The default
          is 1000.

          '
        in: query
        name: limit
        required: false
        schema:
          default: 1000
          maximum: 1000
          minimum: 1
          type: integer
      - description: 'The number of suppression entries to skip before returning results.
          The default is 0.

          '
        in: query
        name: offset
        required: false
        schema:
          default: 0
          minimum: 0
          type: integer
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuppressionListResponse'
          description: Successfully retrieved all suppression entries associated with
            the account.
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad request. The request is invalid.
        '500':
          description: An unexpected internal error occurred.
      summary: Retrieve Suppression List
      tags:
      - Suppression
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.suppressions.list();\n\nif\
          \ (error) {\n  console.error(\"List suppressions failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY (parent\
          \ or sub-account) before running\")\n\n# Retrieve suppression entries for\
          \ the account.\nresponse = mailchannels.Suppressions.list()\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");


          $client = new Client(apiKey: $api_key);


          // Retrieve suppression entries for the account.

          $response = $client->suppressions->list();


          print_r($response->toArray());'
    post:
      description: 'Creates suppression entries for the specified account.

        Parent accounts can create suppression entries for all associated sub-accounts.

        If suppression_type is not provided, it defaults to ''non-transactional''.

        The operation is atomic, meaning all entries are successfully added or none
        are added if an error occurs.

        '
      parameters:
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SuppressionListInput'
        description: The details of the suppression entries to create.
        required: true
      responses:
        '201':
          description: All suppression entries were successfully created.
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad request. The request body is invalid.
        '409':
          description: 'Conflicts.

            One or more suppression entries in the request already exist and

            cannot be created again.

            '
        '413':
          description: 'Payload too large.

            The request exceeds the maximum allowed total of 1000 suppression entries

            for the parent account and/or its sub-accounts.

            '
        '500':
          description: An unexpected internal error occurred.
        '503':
          description: Temporarily unavailable for maintenance.
      summary: Create Suppression Entries
      tags:
      - Suppression
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ RECIPIENT } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"\
          Set MAILCHANNELS_API_KEY before running\");\nif (!RECIPIENT) throw new Error(\"\
          Set RECIPIENT to the email address to suppress\");\n\nconst mailchannels\
          \ = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst { success, error }\
          \ = await mailchannels.suppressions.create({\n  entries: [{ recipient: RECIPIENT\
          \ }],\n});\n\nif (!success) {\n  console.error(\"Create suppression failed:\"\
          , error);\n  process.exit(1);\n}\nconsole.log(\"Suppression created\");"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY (parent\
          \ or sub-account) before running\")\n\nrecipient = os.environ.get(\"RECIPIENT\"\
          )\nif not recipient:\n    sys.exit(\"Set RECIPIENT to the email address\
          \ to suppress\")\n\nresponse = mailchannels.Suppressions.create([{\"recipient\"\
          : recipient}])\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key   = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $recipient = getenv(''RECIPIENT'') or exit("Error: RECIPIENT is not set\n");


          $client = new Client(apiKey: $api_key);


          $response = $client->suppressions->create([[''recipient'' => $recipient]]);


          print_r($response->toArray());'
  /suppression-list/recipients/{recipient}:
    delete:
      description: 'Deletes suppression entry associated with the account based on
        the specified recipient and source.

        If source is not provided, it defaults to ''api''.

        If source is set to ''all'', all suppression entries related to the specified

        recipient will be deleted.

        '
      parameters:
      - in: path
        name: recipient
        required: true
        schema:
          type: string
      - in: query
        name: source
        required: false
        schema:
          default: api
          enum:
          - api
          - unsubscribe_link
          - list_unsubscribe
          - hard_bounce
          - spam_complaint
          - all
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '204':
          description: The specified suppression entry was successfully deleted.
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad request. The request is invalid.
        '500':
          description: An unexpected internal error occurred.
        '503':
          description: Temporarily unavailable for maintenance.
      summary: Delete Suppression Entry
      tags:
      - Suppression
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ RECIPIENT } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"\
          Set MAILCHANNELS_API_KEY before running\");\nif (!RECIPIENT) throw new Error(\"\
          Set RECIPIENT to the email address whose suppression entry should be removed\"\
          );\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst\
          \ { success, error } = await mailchannels.suppressions.delete(RECIPIENT);\n\
          \nif (!success) {\n  console.error(\"Delete suppression failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(\"Suppression deleted\");"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY (parent\
          \ or sub-account) before running\")\n\nrecipient = os.environ.get(\"RECIPIENT\"\
          )\nif not recipient:\n    sys.exit(\"Set RECIPIENT to the email address\
          \ whose suppression entry should be removed\")\n\n# SOURCE is optional.\
          \ Defaults to \"api\". Pass \"all\" to delete every entry for the recipient.\n\
          source = os.environ.get(\"SOURCE\")\n\nresponse = mailchannels.Suppressions.delete(recipient,\
          \ source=source)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key   = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $recipient = getenv(''RECIPIENT'') or exit("Error: RECIPIENT is not set\n");


          $client = new Client(apiKey: $api_key);


          // SOURCE is optional. Defaults to "api". Pass "all" to delete every entry
          for the recipient.

          $source = getenv(''SOURCE'') ?: null;


          $response = $client->suppressions->delete($recipient, $source);


          print_r($response->toArray());'
  /usage:
    get:
      description: Retrieves usage statistics during the current billing period.
      parameters:
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UsageStats'
          description: Successfully returned the usage stats.
        '500':
          description: Internal Server Error
      summary: Retrieve Usage Stats
      tags:
      - Usage
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.metrics.usage();\n\nif (error)\
          \ {\n  console.error(\"Get usage failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# Retrieve parent-account usage for the current billing\
          \ period.\nresponse = mailchannels.Usage.retrieve()\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");


          $client = new Client(apiKey: $api_key);


          // Retrieve parent-account usage for the current billing period.

          $response = $client->usage->retrieve();


          print_r($response->toArray());'
  /webhook:
    delete:
      description: 'Deletes all registered webhook endpoints for the customer.

        '
      parameters:
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '204':
          description: Successfully removed webhook endpoint(s)
        '500':
          description: Internal Server Error
      summary: Delete Customer Webhooks
      tags:
      - Webhooks
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { success, error } = await mailchannels.webhooks.deleteAll();\n\n\
          if (!success) {\n  console.error(\"Delete webhooks failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(\"All webhooks deleted\");"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# Delete all webhook endpoints enrolled for the account.\n\
          response = mailchannels.Webhooks.delete_all()\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");


          $client = new Client(apiKey: $api_key);


          // Delete all webhook endpoints enrolled for the account.

          $response = $client->webhooks->deleteAll();


          print_r($response->toArray());'
    get:
      description: 'Retrieves all registered webhook endpoints associated with the
        customer.

        '
      parameters:
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                items:
                  $ref: '#/components/schemas/Webhook'
                type: array
          description: Successfully returning customer's webhooks
        '500':
          description: Internal Server Error
      summary: Retrieve Customer Webhooks
      tags:
      - Webhooks
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.webhooks.list();\n\nif (error)\
          \ {\n  console.error(\"List webhooks failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# List all webhook endpoints currently enrolled for the\
          \ account.\nresponse = mailchannels.Webhooks.list()\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");


          $client = new Client(apiKey: $api_key);


          // List all webhook endpoints currently enrolled for the account.

          $response = $client->webhooks->list();


          print_r($response->toArray());'
    post:
      description: 'Enrolls the customer to receive event notifications via webhooks.

        '
      parameters:
      - description: the URL to which the webhook should be sent
        in: query
        name: endpoint
        required: true
        schema:
          maxLength: 8000
          type: string
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '201':
          description: Successfully enrolled customer to receive webhooks
        '400':
          description: Bad Request
        '409':
          description: There's already a webhook endpoint for this customer
        '500':
          description: Internal Server Error
      summary: Enroll for Webhook Notifications
      tags:
      - Webhooks
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ WEBHOOK_ENDPOINT } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new\
          \ Error(\"Set MAILCHANNELS_API_KEY before running\");\nif (!WEBHOOK_ENDPOINT)\
          \ throw new Error(\"Set WEBHOOK_ENDPOINT to the URL that should receive\
          \ events\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { success, error } = await mailchannels.webhooks.enroll(WEBHOOK_ENDPOINT);\n\
          \nif (!success) {\n  console.error(\"Enroll webhook failed:\", error);\n\
          \  process.exit(1);\n}\nconsole.log(\"Webhook enrolled\");"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\nendpoint = os.environ.get(\"WEBHOOK_ENDPOINT\")\nif not\
          \ endpoint:\n    sys.exit(\"Set WEBHOOK_ENDPOINT to the URL that should\
          \ receive events\")\n\n# Enroll a webhook endpoint to receive delivery events.\n\
          response = mailchannels.Webhooks.create(endpoint)\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key  = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $endpoint = getenv(''WEBHOOK_ENDPOINT'') or exit("Error: WEBHOOK_ENDPOINT
          is not set\n");


          $client = new Client(apiKey: $api_key);


          // Enroll a webhook endpoint to receive delivery events.

          $response = $client->webhooks->create($endpoint);


          print_r($response->toArray());'
  /webhook-batch:
    get:
      description: 'Retrieves paged webhook batches associated with the customer.

        The time range specified by created_after and created_before filters

        must not exceed 31 days.

        If neither is specified, the default time range is the last 3 days.

        Optional filters include status categories, webhook, limit and offset.

        '
      parameters:
      - description: 'Inclusive lower bound(UTC) for filtering webhook batches by
          creation time.

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ

          '
        in: query
        name: created_after
        required: false
        schema:
          type: string
      - description: 'Exclusive upper bound(UTC) for filtering webhook batches by
          creation time.

          Formats: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ

          '
        in: query
        name: created_before
        required: false
        schema:
          type: string
      - description: 'Filters webhook batches by webhook response status category.

          Values must be unique and encoded as a comma-separated list in the query
          string.

          If not provided, batches with all categories are returned.

          '
        example: no_response,4xx,5xx
        explode: false
        in: query
        name: statuses
        required: false
        schema:
          items:
            enum:
            - 1xx
            - 2xx
            - 3xx
            - 4xx
            - 5xx
            - no_response
            type: string
          maxItems: 6
          type: array
        style: form
      - description: 'Filters webhook batches by the webhook endpoint to which events
          in the batch were posted.

          '
        in: query
        name: webhook
        required: false
        schema:
          type: string
      - description: 'The maximum number of webhook batches to return

          '
        in: query
        name: limit
        required: false
        schema:
          default: 500
          maximum: 500
          minimum: 1
          type: integer
      - description: 'The number of webhook batches to skip before starting to collect
          the result set

          '
        in: query
        name: offset
        required: false
        schema:
          default: 0
          minimum: 0
          type: integer
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookBatchResult'
          description: 'Successfully returned Webhook batches

            '
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request
        '500':
          description: Internal Server Error
      summary: Retrieve Webhook Batches
      tags:
      - Webhooks
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.webhooks.batches();\n\nif (error)\
          \ {\n  console.error(\"List webhook batches failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# List webhook batches from the last 3 days.\nresponse =\
          \ mailchannels.Webhooks.batches()\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");


          $client = new Client(apiKey: $api_key);


          // List webhook batches from the last 3 days.

          $response = $client->webhooks->batches();


          print_r($response->toArray());'
  /webhook-batch/{batch_id}/resend:
    post:
      description: 'Synchronously resend the webhook batch with the provided batch_id
        for the customer. The result is returned in the

        response.

        '
      parameters:
      - description: the ID of the batch
        in: path
        name: batch_id
        required: true
        schema:
          type: integer
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookResendResponse'
          description: 'Resend attempt completed. The result of the resend attempt
            is included in the response body.

            A successful response here does not mean the webhook endpoint responded
            with a 2xx status code,

            only that we were able to make the resend attempt and receive a response.

            '
        '400':
          description: Bad Request. The batch ID is invalid.
        '404':
          description: The batch ID is not found for the customer.
        '500':
          description: Internal Server Error
      summary: Resend Events
      tags:
      - Webhooks
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ BATCH_ID } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"\
          Set MAILCHANNELS_API_KEY before running\");\nif (!BATCH_ID) throw new Error(\"\
          Set BATCH_ID to the ID of the batch to resend\");\n\nconst mailchannels\
          \ = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst { data, error } = await\
          \ mailchannels.webhooks.resendBatch(Number(BATCH_ID));\n\nif (error) {\n\
          \  console.error(\"Resend webhook batch failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\nbatch_id_str = os.environ.get(\"BATCH_ID\")\nif not batch_id_str:\n\
          \    sys.exit(\"Set BATCH_ID before running\")\n\n# Resend a specific webhook\
          \ batch.\nresponse = mailchannels.Webhooks.resend_batch(int(batch_id_str))\n\
          \nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key  = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $batch_id = getenv(''BATCH_ID'') or exit("Error: BATCH_ID is not set\n");


          $client = new Client(apiKey: $api_key);


          $response = $client->webhooks->resendBatch((int) $batch_id);


          print_r($response->toArray());'
  /webhook/public-key:
    get:
      description: 'Retrieves the public key used to verify signatures on incoming
        webhook payloads.

        '
      parameters:
      - description: the ID of the key
        in: query
        name: id
        required: true
        schema:
          type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Key'
          description: Successfully return the webhook signing key
        '404':
          description: The key is not found
        '500':
          description: Internal Server Error
      summary: Retrieve Webhook Signing Key
      tags:
      - Webhooks
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY,\
          \ KEY_ID } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"\
          Set MAILCHANNELS_API_KEY before running\");\nif (!KEY_ID) throw new Error(\"\
          Set KEY_ID (the signing key ID from the signature-input webhook header)\"\
          );\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\nconst\
          \ { data, error } = await mailchannels.webhooks.getSigningKey(KEY_ID);\n\
          \nif (error) {\n  console.error(\"Get signing key failed:\", error);\n \
          \ process.exit(1);\n}\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\nkey_id = os.environ.get(\"KEY_ID\")\nif not key_id:\n  \
          \  sys.exit(\"Set KEY_ID (the signing key ID from the signature-input webhook\
          \ header)\")\n\nresponse = mailchannels.Webhooks.public_key(key_id)\n\n\
          print(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");

          $key_id  = getenv(''KEY_ID'') or exit("Error: KEY_ID is not set\n");


          $client = new Client(apiKey: $api_key);


          // KEY_ID is the signing key ID from the signature-input webhook header.

          $response = $client->webhooks->publicKey($key_id);


          print_r($response->toArray());'
  /webhook/validate:
    post:
      description: 'Validates whether your enrolled webhook(s) respond with an HTTP
        2xx status code.

        Sends a test request to each webhook containing your customer handle,

        a hardcoded event type(test), a hardcoded sender email(test@mailchannels.com),a
        timestamp,

        a request ID (provided or generated), and an SMTP ID.

        The response includes the HTTP status code and body returned by each webhook.

        '
      parameters:
      - in: header
        name: X-Api-Key
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookValidationRequestBody'
        required: false
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookValidationResults'
          description: 'Webhook validation completed

            '
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
          description: Bad Request. Provided request ID is too long.
        '404':
          description: No webhooks found for the account
        '500':
          description: Internal Server Error
      summary: Validate Enrolled Webhook
      tags:
      - Webhooks
      x-codeSamples:
      - label: Node.js
        lang: javascript
        source: "import { MailChannels } from \"mailchannels-sdk\";\n\nconst { MAILCHANNELS_API_KEY\
          \ } = process.env;\nif (!MAILCHANNELS_API_KEY) throw new Error(\"Set MAILCHANNELS_API_KEY\
          \ before running\");\n\nconst mailchannels = new MailChannels(MAILCHANNELS_API_KEY);\n\
          \nconst { data, error } = await mailchannels.webhooks.validate();\n\nif\
          \ (error) {\n  console.error(\"Validate webhook failed:\", error);\n  process.exit(1);\n\
          }\nconsole.log(data);"
      - label: Python
        lang: python
        source: "import os\nimport sys\n\nimport mailchannels\n\nif not os.environ.get(\"\
          MAILCHANNELS_API_KEY\"):\n    sys.exit(\"Set MAILCHANNELS_API_KEY before\
          \ running\")\n\n# Send a test event to each enrolled webhook and report\
          \ whether it responded\n# with a 2xx status. request_id is optional; if\
          \ omitted, one is generated.\nresponse = mailchannels.Webhooks.validate(request_id=\"\
          test_request_1\")\n\nprint(response)"
      - label: PHP
        lang: php
        source: '<?php


          require_once __DIR__ . ''/vendor/autoload.php'';


          use MailChannels\Client;


          $api_key = getenv(''MAILCHANNELS_API_KEY'') or exit("Error: MAILCHANNELS_API_KEY
          is not set\n");


          $client = new Client(apiKey: $api_key);


          // Send a test event to each enrolled webhook and report whether it responded

          // with a 2xx status. request_id is optional; if omitted, one is generated.

          $response = $client->webhooks->validate(requestId: ''test_request_1'');


          print_r($response->toArray());'
servers:
- url: https://api.mailchannels.net/tx/v1
tags:
- name: Send
- name: DKIM
- name: Metrics
- name: Sub-accounts
- name: Suppression
- name: Webhooks
- name: Usage
- name: Custom Tracking
