Skip to main content
POST

Authentication

Requires X-Agent-ID header with your wallet address.

Request Body

string
Sender email address (e.g., [email protected]).If omitted, the server picks one from the agent’s domain pool via domain rotation: LRU + per-day capacity + warmup-score gates over every pool_status='active' row the caller owns. The chosen address is echoed back as from_address in the response and locked into the quote — the matching /email/send replays it automatically, so the caller can either omit from_address on send or pass the same value. Passing a different address on send returns 400 from_address_mismatch.If provided, the pool is bypassed and the server only checks domain ownership. Use this when you want to pin sends to a specific mailbox (e.g. [email protected] vs [email protected]).Pinning also bypasses the warmup-score and daily_send_limit gates — those are enforced only during rotation. If the pinned domain is still warming or over its daily cap the send still proceeds, but the response carries a non-blocking warning (pinned_domain_warming / pinned_over_limit). Reputation and limits are per-domain, shared by every mailbox on it, so multiple mailboxes are not a deliverability or capacity lever.
string | string[]
required
Recipient email address(es)
string
required
Email subject line
string
required
Email body content (plain text)
string
How the domain sends: relay (default) or mailbox. mailbox provisions a real dedicated mailbox per address and prices the one-time mailbox_provisioning_fee on this quote; relay is header-only send (fee 0). Only applies when the domain is first set up. See Send for the full semantics — the quote locks the mode in, so omit mailbox_mode on /email/send to replay it.

Response

string
Domain extracted from from_address
boolean
Whether this is a new domain that needs registration
boolean
Whether the domain is available for registration
number
Cost to register the domain (USD)
number
Cost to send the email (USD)
number
One-time fee (USD) charged the first time you send from an address that needs a real mailbox provisioned on the domain — the address is created and warmed on first use. This applies to every address, including the domain’s default sender (default_from); it’s 0 only once that address is already provisioned and active (see addresses[] on /email/domains). An address whose mailbox is still provisioning or failed re-incurs the fee until it is active.Not every domain provisions a mailbox per address — relay/send-only domains send from any from_address without a per-address mailbox, so this fee is 0 for them regardless. Trust this field on the quote: 0 means nothing extra is billed; a non-zero value is the one-time charge.Surfaced here before payment and folded into total_cost. If you send from a new address without a quote that included this fee, /email/send returns 402 mailbox_provisioning_required (re-quote with the exact from_address).
number
Total cost (registration + service + mailbox provisioning fees)
string
Quote ID to use in the send request
string
Domain status: verified, provisioning, unprovisioned, or blocked
string
Echoed only when the server picked the address (caller omitted it). Use it on /email/send or omit from_address on send — the value is locked into the quote and replayed automatically.
boolean
true when the server picked from the agent’s active pool.
string
Non-blocking advisory. Surface it to the user and consider deferring:
  • pinned_domain_warming — a pinned from_address whose domain is still warming (warmup score below threshold). Pinning bypasses the warmup gate.
  • pinned_over_limit — a pinned domain already at/over its daily_send_limit for today.
The same field appears on the /email/send response. Pinned sends are never blocked by warmup/limit — branch on warning to defer.
string
no_sending_domain (HTTP 400) when you pass no from_address and own no rotation-eligible domain. There is no shared fallback sender — provision a domain (pass a from_domain to register) or pin one you own. reason is empty (no domains) or exhausted (all warming/over-cap).

Bulk Usage

You can request a quote for sending independent emails to multiple recipients in a single request. Pass an array of strings to to_address.
The service_fee will scale based on the number of recipients. The registration_fee (if applicable) remains a one-time cost for the domain.

Domain Rotation

If the caller owns multiple domains (root or subdomains), /email/quote without from_address rotates across them instead of hardcoding one. The selector runs in a single FOR UPDATE SKIP LOCKED query so concurrent quote calls never double-book the same row past its daily cap. Eligibility gates (applied in SQL, AND-combined):
  • agent_id = caller
  • pool_status = 'active' (warming domains stay out of rotation until their reputation warmup score crosses WARMUP_ACTIVE_THRESHOLD)
  • daily_sent_count + recipientCount <= daily_send_limit (per-domain per-UTC-day cap; resets lazily on the first send after midnight)
  • warmup_score IS NULL OR warmup_score >= MIN_ROTATION_SCORE (default 60)
Ordering: last_used_at ASC NULLS FIRST (least-recently-used first). Side effects on success: last_used_at = NOW(), daily_sent_count += recipientCount. Committed at quote time so concurrent quotes can’t race past capacity. If you bail without calling /email/send, the reservation auto-releases (best-effort).

Picking a specific domain

Just pass from_address and the pool is skipped:

Letting the server rotate

The rotated address is always a domain you own; the mailbox local-part is ROTATION_DEFAULT_MAILBOX (env; default agent). For per-mailbox control, pass from_address explicitly. See GET /email/domains to inspect what’s in your pool, and the pause / resume endpoints to take a domain in or out of rotation without removing it.

Notes

  • Domain provisioning happens automatically during the send request
  • Quote is valid for 1 hour
  • For existing verified domains, registration_fee will be 0