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

# Send a message from a Dairo inbox

> Send a message from a Dairo inbox



## OpenAPI

````yaml POST /v1/messages
openapi: 3.1.0
info:
  title: Dairo API
  version: 1.0.0
  summary: Email infrastructure API for AI agents and applications.
  description: >-
    Source-of-truth public Dairo API contract. Operations marked
    x-dairo-status=live are implemented; planned operations define the SDK/CLI
    target surface.
servers:
  - url: https://api.dairo.app
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Messages
    description: Outbound email sending.
  - name: Domains
    description: >-
      A domain lets you send and receive on addresses you own
      (`hello@yourcompany.com`) instead of the shared `dairo.app` domain. Add a
      domain, publish the DNS records Dairo returns, then recheck it to move
      from `pending` to `verified`. Every account also has read-only access to
      the included `dairo.app` domain, which is always verified and cannot be
      modified.
  - name: Inboxes
    description: >-
      An inbox is a send-and-receive address on one of your domains
      (`billing@yourcompany.com`) that carries a routing `mode`, an assigned
      `agent` name, and a `status` of `active`, `paused`, or `deleted`. Create
      an inbox on a `verified` domain, then mail sent to it is stored as a
      message and delivered to your webhooks as a `message.received` event. You
      can also mint an inbox on the shared `dairo.app` domain to receive without
      adding a domain of your own.
  - name: Webhooks
    description: >-
      Register HTTPS endpoints that receive Dairo account events — new inbound
      mail, delivery and bounce receipts, budget trips, letter and domain status
      changes, and more — as signed JSON `POST` requests. Each subscription has
      its own signing secret, and deliveries are retried automatically, logged
      per attempt, and can be paused, resumed, redriven, or test-pinged. Verify
      every request with the `X-Dairo-Signature` header before trusting its
      payload.
  - name: API Keys
    description: >-
      Programmatic credentials for the Dairo API. Each key holds an explicit set
      of `scopes` and an optional IP allowlist, and its secret is returned only
      once — at creation. A key that carries `keys:write` can mint additional
      keys, but only with scopes that are a subset of its own.
  - name: Messages
    description: >-
      Send messages and read what comes back, across every channel Dairo
      carries. One `POST /v1/messages` call delivers email, agent-to-agent,
      Telegram, Slack, or SMS from one of your inboxes, and `GET /v1/messages`
      returns inbound, outbound, and internal messages as a single unified list.
      The same surface exposes a send's delivery events, scheduled-send
      cancellation, bulk deletion, Telegram message actions, and attachment
      metadata.
  - name: Threads
    description: >-
      Threads group the inbound and outbound messages of a single email or
      agent-to-agent conversation under one `subject`, scoped to the inbox they
      belong to. Dairo opens and updates threads automatically as messages
      arrive and send, so this resource is read-only: list threads by recent
      activity, or fetch one thread with its messages. Both calls require the
      `messages:read` scope.
  - name: Audiences
    description: >-
      Reusable email recipient lists and list broadcasts. Create an audience,
      add members by raw address or by contact reference, then broadcast a
      single message that fans out asynchronously to every active member.
  - name: Outbound
    description: Outbound email history and delivery events.
  - name: Templates
    description: >-
      Reusable email templates written as React email components, backed by an
      append-only history of immutable versions. Creating a template publishes
      version `1`; publish a new version whenever the content changes, and
      re-point the mutable `currentVersion` pointer to roll forward or back
      instantly. Reference a template by `id` or `slug` when you [send a
      message](/sending/sending-email), and Dairo validates your `variables`
      against the pinned version's schema before the message goes out.
  - name: Budgets
    description: >-
      Budgets are fail-closed spending and volume ceilings enforced inside the
      send path. Attach one to your whole `account`, to a single API `key`, or
      to an `agent`, and every send is checked against its limits before it is
      accepted. A send over the line is rejected with a `budget_exceeded` error
      and emits a `budget.tripped` event.
  - name: Events
    description: >-
      A durable, ordered ledger of every delivery event on your account —
      outbound sends, delivery outcomes such as `email.delivered` and
      `email.bounced`, and inbound `message.received`. Read it forward from a
      cursor to catch up after downtime, spot lost events by their sequence
      gaps, and replay any slice back to your webhooks. Each ledger row mirrors
      the webhook event for the same source event, so the same `eventId` lines
      up across live delivery and replay.
  - name: Agents
    description: >-
      An Agent Passport gives one of your agents a durable, portable identity: a
      stable `agt_...` id and an account-wide Ed25519 signing key. Bind an API
      key or an inbox to a passport and every message that key or inbox sends
      carries a signed `X-Dairo-Provenance` header, letting any recipient
      confirm the message really came from your agent by checking it against
      Dairo's public JWKS. The verify and JWKS endpoints are public and
      unauthenticated; creating, reading, binding, and deleting passports run on
      your API key.
  - name: Compliance
    description: >-
      Prove and enforce EU data governance from your own automation. Export a
      tamper-evident, hash-chained audit ledger with an `EdDSA`-signed
      verification manifest, run irreversible subject-erasure and inbox-purge
      jobs that return signed deletion certificates, and read a
      machine-checkable residency posture with a monotonic subprocessor list —
      every signed artifact verifies against Dairo's published JWKS, so an
      auditor never has to trust the API on its word.
  - name: Conversation Autopilot
    description: >-
      Register a durable background wait on an inbox and let Dairo resolve an
      inbound email for you. Each wait watches the inbox's incoming mail; an
      EU-resident AI matcher decides which message satisfies a natural-language
      `instruction` and extracts the value you asked for — a one-time code, a
      reset link, or a confirmation line. The outcome arrives as a
      `verification.resolved` or `verification.expired` event on your webhook
      and the durable event ledger, or by polling the wait.
  - name: Letters
    description: >-
      Send physical mail by API. Dairo prints your PDF, envelopes it, and posts
      it, then keeps a live `status` and event timeline through delivery.
      Templates and batches personalize one design and send it to up to 1,000
      recipients per call.
  - name: Buckets
    description: >-
      Buckets are owner-scoped containers for stored files. Every account starts
      with a default bucket, plus a reserved bucket that holds inbound email
      attachments. Uploads follow a two-step flow — request an upload URL, `PUT`
      the bytes to it, then finalize to record the object — and every object is
      malware-scanned before it can be shared. Reads require the `buckets:read`
      scope; writes require `buckets:write`.
  - name: Contacts
    description: >-
      A channel-agnostic address book. Each contact is one identity — a
      `person`, an `agent`, or the project `self` contact — with any number of
      `handles`, one per channel address (`email`, `a2a`, `telegram`, `postal`,
      and more). Store a contact once and address it anywhere by `@alias`,
      `contact:<id>`, or `@me` instead of repeating raw addresses; Dairo also
      links inbound messages to the sender's contact so you can read a full
      cross-channel history.
  - name: Phone
    description: >-
      Place outbound AI phone calls and manage the phone numbers that place
      them. A call is asynchronous — you place it, then poll for its status,
      transcript, recording, and a structured summary — while numbers are
      searched in carrier inventory, provisioned, bound to an inbox or agent,
      and released. Reads use the `phone:read` scope, number provisioning uses
      `phone:write`, and dialing a person uses `phone:call`.
  - name: Slack
    description: >-
      Connect Slack workspaces so a bot running on your own Slack app appears in
      the unified inbox. Register a managed or bring-your-own Slack app, mint an
      "Add to Slack" install URL for your customers, and inbound @mentions and
      DMs arrive as threads that fire the `message.received` webhook. See
      [connecting Slack](/channels/slack) for the end-to-end flow.
  - name: Account
    description: >-
      Introspect the account behind the API key making the request — its
      identity, the key's scopes, the current plan, live usage counters, and
      remaining storage. The resource is a single read-only call you use to
      confirm a key works and to check headroom before a large send or upload.
  - name: Attachments
    description: >-
      Attachments are the files carried on a message — the documents and images
      on inbound email, and files you attach when sending. These endpoints read
      a stored attachment: fetch its raw bytes directly, or mint a short-lived
      signed URL you can hand to a browser or another service. Every read is
      scoped through the message that owns the attachment and gated by a
      security scan, and all three require the `messages:read` scope.
  - name: Audit Logs
    description: >-
      An append-only, tamper-evident record of governance-relevant control-plane
      actions on your account — resource creation and deletion, API key and
      webhook management, membership and organization changes. Entries are
      written automatically as you and your keys act; they cannot be created,
      edited, or deleted through the API. Reading requires the `account:read`
      scope.
  - name: MCP
    description: >-
      A single public endpoint that advertises the Dairo hosted MCP server's
      tool surface — which tools an agent can call, the scopes each one needs,
      and a content-hash version you can poll cheaply. Point an MCP-aware client
      at it to discover Dairo's tools without authenticating, or pass a key to
      see which tools that key is allowed to call.
  - name: Notifications
    description: >-
      Control which categories of account email Dairo sends you. Preferences are
      per category — `account`, `billing`, `usage`, `security`, and `product` —
      and each defaults to enabled, so a new account receives every notification
      until you opt a category out.
  - name: Organizations
    description: >-
      An organization is a Dairo project — the isolation tier that owns your
      domains, inboxes, API keys, and every other resource, and that billing and
      membership attach to. Every account belongs to at least one organization
      and holds a `role` of `owner`, `admin`, or `member` in each. These
      dashboard-authenticated endpoints back the organization switcher: they
      list the organizations you belong to and create new ones.
  - name: Reputation
    description: >-
      Every agent carries its own bounce and complaint reputation, tracked over
      a rolling 24-hour window and isolated from your domain and from your other
      agents. When an agent's rates climb, Dairo throttles it and then pauses it
      automatically to protect your sending reputation, exposing the current
      state, the thresholds in force, and a `shouldSend` verdict you can check
      before a batch. Use these endpoints to watch the fleet and to clear an
      agent once you've fixed the underlying cause.
  - name: Schema Inboxes
    description: >-
      Attach an extraction contract to an inbox so inbound mail arrives as
      typed, validated JSON instead of best-effort text. The contract is a flat
      `JSON-Schema-lite` map of field names to type declarations; each incoming
      message is extracted against it, and any extracted object that fails
      validation is either quarantined or passed through per the inbox's policy.
      These endpoints are the control plane — attach, read, and detach the
      contract — while extraction runs automatically on every message the inbox
      receives.
  - name: Telegram
    description: >-
      The catalog of text-to-speech voices you can attach to a
      [Telegram](/channels/telegram) voice message. Browse it to find a voice,
      then pass that voice's `slug` as `telegram.voice.voiceId` when you send.
      Omitting `voiceId` uses the account default voice (`adrian`).
paths:
  /v1/messages:
    post:
      tags:
        - Messages
      summary: Send a message from a Dairo inbox
      description: >-
        Sends one message from the inbox named by `inboxId` to the addresses in
        `to` (plus optional `cc`/`bcc`, up to 50 recipients total); the inbox's
        own channel decides the transport — email, Telegram, Slack, or SMS.
        Provide exactly one body source — `text`, `html`, `react`, or a stored
        `template` — or send attachment-only (or a Telegram-only payload); zero
        or more than one body source is a `400`. An immediate send delivers
        synchronously and returns the definitive `status` (`sent` with a
        `providerMessageId`, or `failed`), while a send with a future `sendAt`
        (RFC3339, at most 30 days out) returns `status: scheduled` after passing
        every gate. Set the `Idempotency-Key` header (or the body field
        `idempotencyKey`, ≤128 characters) so a retried send returns the
        original result instead of delivering twice. Inline base64 `attachments`
        are capped at 8 MiB each and 8 MiB per send across at most 10 files;
        attach a stored object by `objectId` to send up to 24 MiB. A delivered
        send emits the `message.sent` webhook event and is metered for billing
        per recipient (`to` + `cc` + `bcc`); it requires the `messages:send`
        scope, and [sending email](/sending/sending-email) shows the full
        request shape. Set `dryRun: true` to validate a send without performing
        it: the request is checked exactly as a real send would be and a
        non-persisted preview (`status: "preview"`) comes back, with nothing
        created, queued, sent, metered, or billed. Test mode is scoped to the
        REQUEST, not to the credential — a `dairo_test_` API key still sends
        real, billable mail.
      operationId: sendMessage
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendMessageRequest'
      responses:
        '202':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SendMessageResponse'
        '400':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        maxLength: 128
      description: Optional idempotency key for safe retries of side-effecting operations.
  schemas:
    SendMessageRequest:
      type: object
      required:
        - inboxId
        - to
      properties:
        inboxId:
          type: string
        to:
          $ref: '#/components/schemas/Recipients'
        cc:
          $ref: '#/components/schemas/Recipients'
        bcc:
          $ref: '#/components/schemas/Recipients'
        subject:
          type: string
          default: ''
        text:
          type: string
        html:
          type: string
        idempotencyKey:
          type: string
          maxLength: 128
          description: >-
            Body-level idempotency key kept for current API compatibility.
            Prefer Idempotency-Key header for new clients.
        attachments:
          type: array
          description: >-
            Outbound send attachments. 'attachment' and safe 'auto' sends are
            inline; current inline API limit is 10 files, 8 MiB per file, 8 MiB
            total decoded bytes. 'link' is explicit and must be backed by a
            pre-created Dairo share link placed deliberately in text/html by the
            caller.
          items:
            $ref: '#/components/schemas/SendMessageAttachment'
          maxItems: 10
        react:
          $ref: '#/components/schemas/ReactRenderInput'
        template:
          $ref: '#/components/schemas/MessageTemplateRef'
        sendAt:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            RFC 3339 timestamp WITH an explicit timezone offset to schedule the
            send for a future time (max 30 days ahead). Omit to send
            immediately. A scheduled email starts with status scheduled and can
            be stopped via POST /v1/outbound-emails/{emailId}/cancel before it
            fires.
        channel:
          type: string
          enum:
            - email
            - a2a
          description: >-
            Optional explicit delivery channel. "email" forces SES even when
            every recipient is a Dairo inbox; "a2a" requires every recipient to
            be a Dairo inbox (400 otherwise) and cannot combine with sendAt.
            Absent = auto (a2a when all recipients are internal, else email).
            Unknown values are a 400.
        replyTo:
          type: string
          format: email
          description: >-
            Optional single Reply-To address, set verbatim as the MIME Reply-To
            header.
        headers:
          type: object
          additionalProperties:
            type: string
          description: >-
            Optional custom MIME headers ({name: value}). Spoofable/provenance
            headers are dropped server-side; malformed names or CR/LF are
            rejected.
        tags:
          type: object
          additionalProperties:
            type: string
          description: >-
            Optional SES message tags ({name: value}), validated against SES tag
            constraints.
        ignoreComplaints:
          type: boolean
          default: false
          description: >-
            Override complaint suppression for recipients that previously
            complained.
        contactId:
          type: string
          description: >-
            Optional contact reference: the contact's PRIMARY handle for the
            sending inbox's channel is added to `to`, so a send needs no raw
            address. Accepts a bare contact id, or a `contact:<id>` / `@alias` /
            `@me` ref. Recipients in to/cc/bcc may ALSO be contact references
            (`@alias`, `contact:<id>`, `@me`); raw addresses pass through
            unchanged.
        buttons:
          type: array
          description: >-
            Telegram inline keyboard (Telegram-channel inbox only): rows of
            {text, url|callback} buttons. A URL button opens a link; a callback
            button surfaces the tap back to you as an inbound button_tap event
            and shows a feedback toast on tap (default: ✓ + the button label;
            set alert:true for a modal).
          items:
            type: array
            items:
              $ref: '#/components/schemas/TelegramButton'
        dryRun:
          type: boolean
          default: false
          description: >-
            Per-request dry run, at parity with the letters API's dryRun. When
            true the request is validated and the sending inbox resolved exactly
            as a real send would be, then a non-persisted MessagePreview (status
            "preview") is returned: nothing is created, queued, handed to the
            provider, metered, or billed. Absent or false is a normal send. Test
            mode is scoped to the REQUEST, not to the API key — an API key's
            `environment` label has no effect on delivery.
      anyOf:
        - required:
            - text
        - required:
            - html
        - required:
            - react
        - required:
            - template
      additionalProperties: false
    SendMessageResponse:
      type: object
      required:
        - id
        - status
        - warnings
      properties:
        id:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - sent
            - scheduled
            - failed
            - queued
          description: >-
            A single immediate send (POST /v1/emails without sendAt) is
            performed synchronously and returns 'sent' (with providerMessageId)
            or 'failed' — it is never accepted as 'queued' only to fail later on
            something knowable at submit time (oversized attachment, unverified
            sender, etc.). A scheduled send (sendAt in the future) returns
            'scheduled'. 'queued' is returned ONLY for a bulk list broadcast
            (POST /v1/audiences/{id}/send), whose batches are delivered
            asynchronously by the worker fleet.
        providerMessageId:
          type:
            - string
            - 'null'
        error:
          type:
            - string
            - 'null'
          description: >-
            Public-safe failure code/message. Provider/internal text is stored
            internally and never returned to API clients.
        warnings:
          type: array
          description: >-
            Warning-only delivery guidance. Complaint suppressions do not block
            sending; agents should surface these warnings before further
            contact.
          items:
            $ref: '#/components/schemas/SendMessageWarning'
        channel:
          type: string
          enum:
            - email
            - a2a
          description: >-
            The channel this send transited: "email" (SES) or "a2a" (internal
            Dairo-to-Dairo, delivered as a receipt, providerMessageId 'a2a_…').
        channelMetadata:
          type:
            - object
            - 'null'
          additionalProperties: true
          description: >-
            Channel-specific delivery metadata. For a2a: {receiptId, provenance,
            provenanceVerified}. For email: provider send metadata.
        scheduledAt:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            When a scheduled send will fire (RFC3339); present only when status
            is "scheduled".
      additionalProperties: false
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
      additionalProperties: false
    Recipients:
      oneOf:
        - type: string
          format: email
        - type: array
          items:
            type: string
            format: email
          minItems: 1
          maxItems: 50
    SendMessageAttachment:
      type: object
      description: >-
        An outbound attachment. Provide EITHER inline bytes (contentBase64) OR a
        storage reference (objectId) — exactly one, never both. Inline
        attachments require filename and are capped at 8 MiB decoded (API
        Gateway JSON/base64 envelope). A storage-reference attachment names a
        Dairo storage object you own (the objectId returned by a bucket upload's
        finalize, or any owned storage object); Dairo fetches its bytes
        server-side and native-attaches up to 24 MiB, deriving filename and
        contentType from the object unless you override them here. Over 24 MiB
        the send fails with a 413 (create a share link and place it in the body
        yourself; Dairo never auto-edits the body).
      oneOf:
        - required:
            - filename
            - contentBase64
          not:
            required:
              - objectId
        - required:
            - objectId
          not:
            required:
              - contentBase64
      properties:
        filename:
          type: string
          minLength: 1
          maxLength: 120
          description: >-
            Required for an inline (contentBase64) attachment. Optional for a
            storage-reference (objectId) attachment, where it overrides the
            object's stored filename; when omitted the object's filename is
            used.
        contentType:
          type: string
          default: application/octet-stream
          description: >-
            Optional. For a storage-reference (objectId) attachment, overrides
            the object's stored content type; when omitted the object's content
            type is used.
          examples:
            - application/pdf
        contentBase64:
          type: string
          contentEncoding: base64
          description: >-
            Base64-encoded inline attachment bytes. Mutually exclusive with
            objectId. Dairo inline attachment delivery is capped at 8 MiB
            decoded total to stay below API Gateway JSON/base64 envelope limits
            and SES v2 40 MB message limits. For larger files, upload to a Dairo
            bucket and reference it via objectId (native-attached up to 24 MiB).
        objectId:
          type: string
          description: >-
            Storage-reference attachment: the id of a Dairo storage object you
            own. Mutually exclusive with contentBase64. Dairo resolves the
            object with an ownership check, fetches its bytes server-side, and
            native-attaches up to 24 MiB; over that the send fails with a 413
            (no share link is auto-added). filename and contentType are derived
            from the object unless overridden here.
        delivery:
          type: string
          enum:
            - attachment
            - link
            - auto
          default: attachment
          description: >-
            Explicit delivery mode. 'attachment' sends inline as a normal email
            attachment. 'auto' sends inline only when safely below inline
            limits; otherwise callers should use an explicit share-link flow.
            'link' never mutates the email body automatically and this send
            endpoint does not create standalone file links; create/get a Dairo
            share link first and place it in text/html yourself.
      additionalProperties: false
    ReactRenderInput:
      type: object
      required:
        - source
      properties:
        source:
          type: string
          maxLength: 65536
          description: >-
            React Email TSX/JSX component source. Rendered asynchronously by
            Dairo in an isolated renderer with allowlisted React Email imports.
        props:
          type: object
          description: >-
            JSON props passed to the default exported email component.
            Serialized size limit: 32 KiB.
          additionalProperties: true
      additionalProperties: false
    MessageTemplateRef:
      type: object
      description: >-
        Send by referencing a stored template instead of an inline body.
        Mutually exclusive with text, html, and react: combining a template with
        any inline body is a 400. The referenced version is resolved and pinned
        at request time; supplied variables are validated against that version's
        variable schema (a bad variable is a synchronous 400). When the version
        declares a subject template it is used unless an explicit subject is
        provided on the request.
      required:
        - id
      properties:
        id:
          type: string
          description: Template UUID or slug, owned by the authenticated account.
        version:
          type: integer
          format: int64
          minimum: 1
          description: >-
            Explicit version to pin. Omit to resolve and pin the template's
            current default version at request time. An archived template can
            only be sent with an explicit version.
        variables:
          type: object
          description: >-
            Values for the template's declared variables. Validated against the
            pinned version's variable schema (type, enum, maxLength, url/email
            format, required, defaults). Serialized size limit: 32 KiB.
          additionalProperties: true
      additionalProperties: false
    TelegramButton:
      type: object
      description: >-
        A Telegram inline-keyboard button: a text label plus exactly one of url
        (a http/https/tg link) or callback (an opaque action string surfaced
        back to you as an inbound button_tap event). A callback button shows a
        feedback toast on tap (default: ✓ + the button label); set alert:true
        for a modal. feedback/alert are ignored on a url button.
      properties:
        text:
          type: string
          description: Button label (1-64 chars).
        url:
          type: string
          description: >-
            A http://, https://, or tg:// link opened on tap. Mutually exclusive
            with callback.
        callback:
          type: string
          description: >-
            An opaque action string. On tap it is surfaced back to you as an
            inbound button_tap message + a message.button.tapped event. Mutually
            exclusive with url.
        feedback:
          type: string
          description: >-
            Callback-button only: the toast text shown to the tapping user
            (answerCallbackQuery text, max 200 chars). Defaults to '✓ <button
            label>' when omitted, so every tap gives visible feedback. Ignored
            on a url button.
        alert:
          type: boolean
          description: >-
            Callback-button only: when true, the feedback is shown as a modal
            dialog (show_alert) instead of a transient toast. Ignored on a url
            button.
    SendMessageWarning:
      type: object
      required:
        - recipient
        - reason
        - message
      properties:
        recipient:
          type: string
          format: email
        reason:
          type: string
          enum:
            - complaint
        message:
          type: string
          example: >-
            Recipient previously complained; do not contact again unless you are
            sure.
        sourceMessageId:
          type:
            - string
            - 'null'
          format: uuid
          description: >-
            Dairo emailId that originally produced the complaint warning, when
            known.
        providerMessageId:
          type:
            - string
            - 'null'
          description: Provider correlation ID for the complaint event, when known.
        complaintFeedbackType:
          type:
            - string
            - 'null'
        complaintUserAgent:
          type:
            - string
            - 'null'
        lastEventAt:
          type:
            - string
            - 'null'
          format: date-time
      additionalProperties: false
    Error:
      type: object
      required:
        - message
      properties:
        message:
          type: string
        code:
          type: string
        type:
          type:
            - string
            - 'null'
        param:
          type:
            - string
            - 'null'
      additionalProperties: false
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Dairo API key, e.g. dairo_test_... or dairo_live_...

````