Skip to main content
POST

Authentication

Requires x402 payment proof in the X-Payment-Proof header.

Headers

string
required
Quote ID from the /email/quote endpoint. Must match an unused quote owned by the same wallet.
string
required
x402 EIP-712 signature authorising the quoted total_cost.

Request Body

string
Sender email address.Required if the matching quote did NOT come from rotation (you passed from_address when calling /email/quote).Optional if rotation picked the address at quote time — the server replays the locked_from_address from the quote. You can pass the same value as a sanity check, but a different value returns 400 from_address_mismatch (the agent paid for slot A and can’t send from slot B).
string
Display name for the sender. Rendered as From: From Name <from_address> — e.g. Jane Doe <[email protected]>. Max 100 characters; may not contain newlines or angle brackets.
string
How the domain sends when first set up: relay (default) or mailbox.
  • relay — header-only send: any from-address works with nothing provisioned per address (no mailbox fee).
  • mailbox — a real dedicated mailbox per address (better deliverability + per-address warmup). Each new from-address provisions a mailbox and adds a one-time mailbox_provisioning_fee to the quote.
Set this on /email/quote, not here. The quote prices the fee and locks the mode; on /email/send the mode is replayed from the paid quote, so mailbox_mode should be omitted. Re-passing mailbox here is redundant and returns 400 mailbox_mode_conflict if the domain is a live relay domain. Only applies while a domain is unprovisioned — use it on a new from_domain; an already-provisioned domain keeps the mode it was created with.
string | string[]
required
Recipient email address(es)
string
required
Email subject line
string
required
Email body content (plain text)
array
Array of attachment objects with filename, content_type, and content (base64)

Response

string
Job ID for tracking the email send status
string
Job status: pending, processing, completed, or failed
string
Status message
string
Non-blocking deliverability advisory — the send still proceeds. Branch on this to defer rather than treating it as an error:
  • pinned_domain_warming — you pinned a from_address whose domain is still warming (low warmup score). Pinning bypasses the warmup gate, so this is the only signal you’ll get.
  • pinned_over_limit — your pinned domain is over its daily_send_limit today.
Pinned sends are still counted against the domain’s daily_sent_count, but they are not blocked by the limit or warmup score (only rotation enforces those). See List Domain Pool.

Bulk Sending

To send the same email content to multiple recipients, pass an array of email addresses in the to_address field. Each recipient will receive an individual email (not CC/BCC).

Domain Provisioning

If the domain is new, OneShot will automatically:
  1. Register the domain
  2. Configure DNS records
  3. Set up email sending infrastructure
  4. Verify domain ownership
This process typically takes 2-5 minutes. The email will be sent once provisioning completes.

Errors

Notes

  • Quote must be used within 1 hour
  • Domain provisioning is automatic - no additional steps required
  • Job status can be polled using the request_id
  • When rotation picks for you, the from_address is locked into the quote — see /email/quote