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

# Create Inbox

> Provision a new Puffle-managed inbox on a verified custom domain and register it for warmup.

**CLI:**

```bash theme={null}
puffle email account create --username <username> --domain-id <domain-id>
puffle email account create --username <username> --domain-id <domain-id> --display-name <display-name> --first-name <first-name> --last-name <last-name>
```

## Overview

Provisions a new inbox. The server creates the backing inbox on a verified custom domain, registers the account for warmup, creates/assigns the account tag, and inserts the row into the `accounts` table with `type = "email"`.

Warmup analytics live behind a separate endpoint — `GET /api/email/accounts/warmup-analytics` — and are not returned here.

<Note>
  This operation shares the URL path `/api/email/accounts` with the list verb. See [List inboxes](/api-reference/senders/list-email-accounts) to enumerate existing inboxes.
</Note>

## AI agent notes

<Note>
  **Prerequisite: a verified domain.** `createEmailAccount` rejects any `domain_id` whose backing `email_domains.status` is not `verified`. The usual flow is:

  1. `createEmailDomain` — register the domain, DNS auto-synced when Puffle can manage the zone.
  2. Poll `verifyEmailDomain` with `?poll=true` on a cadence until `status === "verified"` (or `status === "failed"`).
  3. Only then call `createEmailAccount` with that `domain_id`.

  **Side effects on create.** Several external operations run in sequence: backing inbox creation, warmup registration, tag creation/assignment, and the final Supabase insert. If any step after inbox creation fails, the backing inbox is cleaned up when possible. Some backing providers block reusing the local part of a previously-deleted inbox — callers will see a 409 if they try.

  **Warmup blocks sending.** Accounts with `status: "warming"` will NOT send campaign emails until warmup completes (or is disabled). Plan for a warmup window before scheduling the first real campaign.
</Note>


## OpenAPI

````yaml post /api/email/accounts
openapi: 3.0.3
info:
  title: Puffle API
  version: 1.0.0
  description: >-
    HTTP API for the Puffle GTM platform - Feed and Lead Finder search
    preparation, campaign-backed Outbound execution, Puffle Agent runs, sender
    management, and Unibox reply workflows. Designed for operation by both
    humans and autonomous AI agents. Agents should start at the [Agent
    Playbook](/guides/agent-playbook) which prescribes a workspace-context check
    (`GET /api/context`) and core user journeys with exact call ordering.
  contact:
    name: Puffle Support
    url: https://puffle.ai
servers:
  - url: https://app.puffle.ai
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Campaigns
    description: >-
      Campaign-backed Outbound execution. These endpoints manage draft,
      launching, active, paused, and completed Outbound runs with sequence
      nodes, contacts, and sender accounts.
  - name: Accounts
    description: Signed-in user account, settings, and workspace context endpoints.
  - name: Billing
    description: Billing customer portal and account billing endpoints.
  - name: Senders
    description: >-
      Connected sender accounts, email inboxes, sending domains, DNS
      verification, warmup, and sender capacity.
  - name: Socials
    description: >-
      Read connected LinkedIn and X accounts, review current and archived posts,
      and reconcile publication status. Creating, editing, scheduling,
      publishing, OAuth connection, analytics, and mentions remain
      dashboard-managed workflows and are not part of the public Bearer-token
      API.
paths:
  /api/email/accounts:
    post:
      tags:
        - Senders
      summary: Create Inbox
      description: >-
        Provision a new Puffle-managed inbox on a verified custom domain and
        register it for warmup. Creates the inbox, fetches SMTP/IMAP
        credentials, enables warmup, tags the account, and inserts the row. If
        any post-inbox step fails, the backing inbox is cleaned up when possible
        and any remaining orphan is logged for manual cleanup.
      operationId: createEmailAccount
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                username:
                  type: string
                  minLength: 1
                  description: >-
                    Local part of the email (everything before `@`). Lowercased
                    server-side. Only `a-z`, `0-9`, `.`, `-`, `_` are allowed.
                domain_id:
                  type: string
                  format: uuid
                  description: >-
                    UUID of an `email_domains` row owned by the caller. The
                    domain's `status` must be `verified` — see `POST
                    /api/email/domains/{id}/verify`.
                display_name:
                  description: >-
                    Human-friendly sender name. If omitted and
                    `first_name`/`last_name` are set, `display_name` is derived
                    from them.
                  type: string
                first_name:
                  type: string
                last_name:
                  type: string
              required:
                - username
                - domain_id
              additionalProperties: false
              description: >-
                Required: `username` + `domain_id`. The full address is composed
                as `<username>@<domain>`. Provisioning creates the backing
                inbox, registers warmup, creates or assigns tags, and inserts
                the DB row; partial failures trigger best-effort rollback.
      responses:
        '201':
          description: >-
            Account created. If warmup enablement succeeded, `status` is
            `warming` and `warmup_status` is `warming`. If warmup failed,
            `status` is `pending` and the client can retry via
            `retry-account-warmup`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  account:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                        description: Primary key in the `accounts` table.
                      user_id:
                        type: string
                        format: uuid
                      type:
                        type: string
                        enum:
                          - email
                      domain_id:
                        description: FK to `email_domains.id` — the custom sending domain.
                        type: string
                        format: uuid
                        nullable: true
                      email_address:
                        description: >-
                          Full inbox address, e.g. `sarah@acme.com`. Derived
                          from `<username>@<domain>` at creation.
                        type: string
                        format: email
                        nullable: true
                      agentmail_inbox_id:
                        description: >-
                          Backing inbox identifier. Used internally for
                          send/reply routing and inbound webhook dedupe.
                        type: string
                        nullable: true
                      instantly_account_id:
                        description: >-
                          Warmup account identifier. Present while the account
                          is registered for warmup analytics; legacy field.
                        type: string
                        nullable: true
                      status:
                        type: string
                        enum:
                          - pending
                          - warming
                          - active
                          - disconnected
                        description: >-
                          Account readiness. Newly-created inboxes are `warming`
                          (warmup running) or `pending` (warmup failed at
                          creation). `active` accounts can send campaign emails.
                      warmup_status:
                        description: >-
                          Warmup lifecycle. Campaigns will NOT send from
                          accounts with `warming` status unless an admin
                          override is enabled.
                        type: string
                        enum:
                          - not_started
                          - warming
                          - completed
                          - disabled
                        nullable: true
                      is_default_sender:
                        type: boolean
                        description: >-
                          Whether this inbox is the user's default email sender.
                          New accounts get one default warmed sender during
                          onboarding.
                      display_name:
                        type: string
                        nullable: true
                      first_name:
                        type: string
                        nullable: true
                      last_name:
                        type: string
                        nullable: true
                      signature:
                        description: >-
                          Per-account email signature. Synced before PATCH
                          completes; newlines become `<br>` for HTML rendering.
                        type: string
                        nullable: true
                      instantly_tag_id:
                        type: string
                        nullable: true
                      instantly_warmup_tag_id:
                        type: string
                        nullable: true
                      created_at:
                        type: string
                        format: date-time
                      updated_at:
                        type: string
                        format: date-time
                        nullable: true
                      email_domains:
                        type: object
                        properties:
                          id:
                            type: string
                            format: uuid
                          domain:
                            type: string
                          status:
                            type: string
                            enum:
                              - pending
                              - verifying
                              - verified
                              - failed
                            description: >-
                              Lifecycle status of the backing custom domain.
                              Only `verified` domains can be used to create new
                              inboxes.
                        required:
                          - id
                          - domain
                          - status
                        additionalProperties: false
                        description: >-
                          Compact domain reference joined onto each account row
                          so clients can show which custom sending domain an
                          inbox belongs to without a second round-trip.
                        nullable: true
                    required:
                      - id
                      - user_id
                      - type
                      - domain_id
                      - email_address
                      - agentmail_inbox_id
                      - instantly_account_id
                      - status
                      - warmup_status
                      - is_default_sender
                      - display_name
                      - first_name
                      - last_name
                      - signature
                      - instantly_tag_id
                      - instantly_warmup_tag_id
                      - created_at
                      - updated_at
                      - email_domains
                    additionalProperties: false
                    description: >-
                      A Puffle-managed email sending inbox. Each account row
                      maps to one backing inbox and optional warmup
                      registration.
                required:
                  - account
                additionalProperties: false
        '400':
          description: >-
            Validation failure or the backing domain is not verified. Common
            causes: missing `username`/`domain_id`, invalid username characters,
            or the verification service reports the domain as unverified (DB
            auto-corrected to `pending`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '401':
          description: Missing or invalid Bearer token.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '402':
          description: >-
            Warmup cannot be registered because the backing warmup workspace is
            not enabled. The inbox is rolled back.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '404':
          description: '`domain_id` does not point at a domain owned by the caller.'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '409':
          description: >-
            An account with this email already exists, this domain already has
            five inboxes, or the backing inbox service rejects reuse of a
            previously-deleted local part.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
        '500':
          description: >-
            A provisioning step failed. Common causes: backing inbox creation,
            warmup registration, or the final DB insert (with best-effort
            rollback of the backing inbox).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                required:
                  - error
                additionalProperties: false
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: pk_live_...

````