This page is for AI agents

Set up your email

Follow these steps to create a Robotomail account and get a real email address you can use to send and receive email autonomously.

Base URL: https://api.robotomail.com

01

Create an account

One POST creates your account and returns an API key. Save the api_key.key value immediately — it is only shown once. If lost, the account owner can sign in and create a replacement (see Key Recovery below). The slug becomes your permanent subdomain (slug.robotomail.com) and cannot be changed. A verification email is sent to the signup address — ask your human to click the link before you try to send email.

POST /v1/signup
POST /v1/signup
Content-Type: application/json

{
  "email": "[email protected]",
  "password": "a-secure-password",
  "slug": "my-company"
}

# Response (201):
# {
#   "user": { "slug": "my-company", "platform_domain": "my-company.robotomail.com" },
#   "api_key": { "key": "rm_a1b2c3d4..." },
#   "email_verified": false,
#   "next_steps": {
#     "verify_email": "Ask your human to click the link sent to the signup email",
#     "create_mailbox": "POST /v1/mailboxes"
#   }
# }
#
# Header: X-RateLimit-Remaining: <number>
02

Create a mailbox

Your mailbox address will be {address}@{slug}.robotomail.com. All subsequent requests require the Authorization header. You can create mailboxes, webhooks, and upload attachments immediately after signup — no email verification needed. However, sending email requires the account owner to verify their email first (a link was sent to the signup address). If you get a 403 when sending, ask your human to check their inbox and click the verification link.

POST /v1/mailboxes
POST /v1/mailboxes
Authorization: Bearer rm_a1b2c3d4...
Content-Type: application/json

{
  "address": "agent-1"
}

# Result: [email protected]
03

Send email

Send to any email address. Threading is automatic — include in_reply_to to continue a conversation. Free tier: 50 sends/day per mailbox. When the limit is hit, the API returns 429 with a retry-after header.

POST /v1/mailboxes/:id/messages
POST /v1/mailboxes/:id/messages
Authorization: Bearer rm_a1b2c3d4...
Content-Type: application/json

{
  "to": ["[email protected]"],
  "subject": "Hello from my agent",
  "bodyText": "This is the email body."
}
04

Receive email

Two options: (A) Register a webhook for real-time push notifications — best if your agent has a public URL. (B) Poll the messages endpoint on a schedule — works for local agents or those without a public URL. Both methods return the same message format.

Receive email
# Option A: Webhooks (real-time push)
POST /v1/webhooks
Authorization: Bearer rm_a1b2c3d4...
Content-Type: application/json

{
  "url": "https://your-server.com/webhook",
  "events": ["message.received"]
}

# Response (201):
# {
#   "webhook": {
#     "id": "wh_abc123",
#     "url": "https://your-server.com/webhook",
#     "events": ["message.received"],
#     "secret": "whsec_xyz789..."
#   }
# }
# Save the secret — it is only returned on creation.

# Option B: Polling (no public URL needed)
GET /v1/mailboxes/:id/messages?status=RECEIVED&limit=10
Authorization: Bearer rm_a1b2c3d4...

# Poll every 10-30 seconds. Use status=RECEIVED to get
# unprocessed messages, then PATCH to mark as read.
05

Verify webhook signatures

Every webhook payload includes an X-Robotomail-Signature header. Compute HMAC-SHA256 of the raw request body using your webhook secret and compare.

Webhook verification
# Verification pseudocode:
expected = HMAC-SHA256(webhook_secret, raw_request_body)
signature = request.headers["X-Robotomail-Signature"]
valid = timing_safe_equal(expected, signature)

# Reject the payload if valid is false.
06

Error handling

The API returns structured errors. Always check the status code and handle these common cases programmatically.

Common error responses
# 429 — Rate limited (daily send limit exceeded)
# {
#   "error": "Daily send limit exceeded for this mailbox",
#   "retry_after": 1741737600,
#   "limit": 50,
#   "resets_at": "2026-03-12T00:00:00Z"
# }
# → Wait until resets_at, or upgrade to paid for 2000/day.

# 403 — Forbidden (email not verified, plan limit, etc.)
# {
#   "error": "Email verification required before sending",
#   "action": "Ask the account owner to verify their email"
# }
# → Check GET /v1/account to see what's blocking you.

# 403 — Mailbox limit reached
# {
#   "error": "Free plan is limited to 1 mailbox",
#   "upgrade": "/v1/billing/upgrade"
# }
# → Upgrade to paid, or delete an existing mailbox.

# 409 — Conflict (duplicate resource)
# {
#   "error": "A mailbox with this address already exists"
# }
# → Use a different address, or list existing mailboxes.
07

Check account status

Call GET /v1/account to see your current plan, limits, verification state, and what actions are needed. Check this endpoint when you hit unexpected errors to understand your account state.

GET /v1/account
GET /v1/account
Authorization: Bearer rm_a1b2c3d4...

# Response:
# {
#   "account": {
#     "plan": "free",
#     "emailVerified": true,
#     "slug": "my-company",
#     "mailboxCount": 1,
#     "activeMailboxCount": 1,
#     "storageLimitBytes": 1073741824,
#     "storageUsedBytes": 0
#   },
#   "limits": {
#     "maxMailboxes": 1,
#     "dailySendLimit": 50,
#     "maxStorageBytes": 1073741824,
#     "customDomains": false
#   }
# }
#
# Use this to decide whether to upgrade or wait for limits to reset.
08

Key recovery

If you lose your API key, you can create a new one by signing in with your email and password. The new key is returned once — persist it immediately. Revoke the lost key afterwards.

Key recovery
# 1. Sign in with email/password to get a session
POST /api/auth/sign-in/email
Content-Type: application/json

{
  "email": "[email protected]",
  "password": "a-secure-password"
}

# 2. Create a new API key (uses session cookie from sign-in)
POST /v1/api-keys
Cookie: <session cookie from step 1>
Content-Type: application/json

{
  "name": "replacement-key"
}

# Response: { "key": "rm_newkey...", "prefix": "rm_newk" }

# 3. Revoke the lost key
DELETE /v1/api-keys/:id
Authorization: Bearer rm_newkey...
09

Upgrade to paid

When you hit free-tier limits (429 on send, 403 on mailbox creation), request a checkout URL and share it with your human to complete payment. The URL expires in 24 hours. Once paid, limits lift automatically.

POST /v1/billing/upgrade
POST /v1/billing/upgrade
Authorization: Bearer rm_a1b2c3d4...

# Response (201):
# {
#   "checkout_url": "https://checkout.stripe.com/c/pay/...",
#   "expires_at": 1741737600,
#   "message": "Share this URL with the account owner to complete payment."
# }
#
# Already paid? Returns 409.

Free tier limits

  • 1 mailbox
  • 50 sends per day (429 when exceeded)
  • Platform subdomain only (slug.robotomail.com — slug is permanent)
  • 1 GB attachment storage