Skip to main content
POST
/
api
/
email
/
accounts
Create Inbox
curl --request POST \
  --url https://app.puffle.ai/api/email/accounts \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "username": "<string>",
  "domain_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "display_name": "<string>",
  "first_name": "<string>",
  "last_name": "<string>"
}
'
{
  "account": {
    "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "user_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "type": "email",
    "domain_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
    "email_address": "jsmith@example.com",
    "agentmail_inbox_id": "<string>",
    "instantly_account_id": "<string>",
    "display_name": "<string>",
    "first_name": "<string>",
    "last_name": "<string>",
    "signature": "<string>",
    "instantly_tag_id": "<string>",
    "instantly_warmup_tag_id": "<string>",
    "created_at": "2023-11-07T05:31:56Z",
    "updated_at": "2023-11-07T05:31:56Z",
    "email_domains": {
      "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
      "domain": "<string>"
    }
  }
}
CLI:
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.
This operation shares the URL path /api/email/accounts with the list verb. See List inboxes to enumerate existing inboxes.

AI agent notes

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.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json

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.

username
string
required

Local part of the email (everything before @). Lowercased server-side. Only a-z, 0-9, ., -, _ are allowed.

Minimum string length: 1
domain_id
string<uuid>
required

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
string

Human-friendly sender name. If omitted and first_name/last_name are set, display_name is derived from them.

first_name
string
last_name
string

Response

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.

account
object
required

A Puffle-managed email sending inbox. Each account row maps to one backing inbox and optional warmup registration.