> ## 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.

# Create an email list

> Create an email list



## OpenAPI

````yaml POST /v1/audiences
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/audiences:
    post:
      tags:
        - Audiences
      summary: Create an email list
      description: >-
        Creates an empty email list and returns the new `audience` object with a
        server-assigned `id`. `name` is required, trimmed, and capped at 120
        characters — an empty or whitespace-only name is a `400`; the optional
        `description` is stored as null when blank. New lists start with
        `status: "active"` and a `memberCount` of 0; populate them with a
        follow-up `POST /v1/audiences/{audienceId}/members`. A successful create
        responds `201`. Requires the `audiences:write` scope.
      operationId: createAudience
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AudienceCreateRequest'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AudienceResponse'
        '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:
    AudienceCreateRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          minLength: 1
        description:
          type: string
    AudienceResponse:
      type: object
      required:
        - list
      properties:
        list:
          $ref: '#/components/schemas/Audience'
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
      additionalProperties: false
    Audience:
      type: object
      required:
        - id
        - name
        - status
        - createdAt
        - updatedAt
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        description:
          type:
            - string
            - 'null'
        status:
          type: string
        memberCount:
          type:
            - integer
            - 'null'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    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_...

````