Email Warm-up API and MCP server
Building an AI SDR, Clay table or n8n workflow? Start with Warm-up API for AI SDRs and outbound agents.
Free with every BobWork Email Warm-up account. Connect mailboxes, watch warm-up health, check SPF, DKIM and DMARC, and run Outbound campaigns from your own code, from Zapier or Make, or straight from an AI assistant such as Claude, ChatGPT or Cursor through MCP.
Quick start
- Sign in at app-emailwarmup.bobwork.ai (free, no card).
- Open API in the sidebar and create a key. It starts with
bwk_and is shown once. - Send it as a Bearer token. JSON in, JSON out. Base URL:
https://app-emailwarmup.bobwork.ai/api/v1
An AI agent can do steps 1 and 2 without a browser: POST https://app-emailwarmup.bobwork.ai/api/v1/signup/code with the person's email, read the 6-digit code from that inbox, then POST https://app-emailwarmup.bobwork.ai/api/v1/signup/verify to get the key. See the agent guide and the OpenAPI spec.
curl https://app-emailwarmup.bobwork.ai/api/v1/mailboxes \ -H "Authorization: Bearer bwk_YOUR_KEY"
Connect mailboxes by API
Three ways, the same as in the app. Every connection is tested before it is saved, and warm-up starts the same day.
Any IMAP/SMTP mailbox (Gmail with an app password, Yahoo, iCloud, Lark, custom domains, SES, SendGrid, Mailgun). Use a preset from GET /providers, or give the hosts yourself.
curl -X POST https://app-emailwarmup.bobwork.ai/api/v1/mailboxes/imap \
-H "Authorization: Bearer bwk_YOUR_KEY" -H "Content-Type: application/json" \
-d '{"email": "sales@yourdomain.com", "password": "APP_PASSWORD", "preset": "gmail-imap", "name": "Sam"}' Gmail / Google Workspace with Google sign-in. Ask for a link, open it, sign in and allow. The mailbox appears in GET /mailboxes a few minutes later.
curl -X POST https://app-emailwarmup.bobwork.ai/api/v1/mailboxes/google/link -H "Authorization: Bearer bwk_YOUR_KEY"
Zoho Mail, free plan included. Create a Self Client at api-console.zoho.com, generate a code, and send the id, secret and code.
curl -X POST https://app-emailwarmup.bobwork.ai/api/v1/mailboxes/zoho \
-H "Authorization: Bearer bwk_YOUR_KEY" -H "Content-Type: application/json" \
-d '{"email": "you@yourdomain.com", "client_id": "1000.XXX", "client_secret": "XXX", "code": "1000.XXX", "dc": "com"}' Everything the API can do
Sign up without a browser
| Method | Endpoint | What it does |
|---|---|---|
| POST | /signup/code | No key needed. {"email": "you@company.com"} emails a 6-digit code to that address (valid 10 minutes) and returns a nonce. |
| POST | /signup/verify | No key needed. {"nonce": "…", "code": "123456", "key_name": "my agent"} returns your API key (bwk_…, shown once). The account is created on first sign-in. Max 5 live keys per account. |
Billing
| Method | Endpoint | What it does |
|---|---|---|
| GET | /billing | Payment status: credit balance, extra-mailbox subscription (active, monthly cost), mailboxes vs free limit, checkouts waiting for payment, prices. Poll it after handing over a checkout link; it confirms a paid checkout straight away. |
| POST | /billing/checkout | Stripe Checkout url for extra mailboxes beyond the free limit: {"yearly": false}. The account owner opens the url and pays; returns already: true if subscribed. |
| POST | /credits/checkout | Stripe Checkout url to top up Outbound credits: {"usd": 10}. Packs: 5, 10, 25 or 100. The account owner opens the url and pays. |
Account
| Method | Endpoint | What it does |
|---|---|---|
| GET | /me | Your email and credit balance. |
| GET | /usage | Free mailbox allowance (10, or 20 for accounts created before 27 October 2026, plus referral bonus), paid extras, referral link and credits. |
| GET | /account | Pool mode (shared network or private pool) and your referral link. |
| POST | /account | Switch pool mode: {"private_pool": true}. |
| GET | /credits | Prepaid credit balance, prices and recent charges. |
Connect mailboxes
| Method | Endpoint | What it does |
|---|---|---|
| GET | /providers | IMAP/SMTP presets with hosts and ports (Gmail app password, Yahoo, iCloud, Zoho, Lark, SES, SendGrid, Mailgun, other). |
| POST | /mailboxes/imap | Connect any mailbox by IMAP + SMTP. The login is tested before it is saved. Over the free limit it is saved paused and the answer has needs_billing:true plus how to pay; paying wakes it. |
| POST | /mailboxes/zoho | Connect Zoho Mail through the Zoho API (free plan works) with a Self Client id, secret and code. |
| POST | /mailboxes/google/link | Get a Google sign-in link for Gmail / Google Workspace. Open it, allow, and the mailbox appears by itself. |
Mailboxes
| Method | Endpoint | What it does |
|---|---|---|
| GET | /mailboxes | Every mailbox: warm-up day, status, 7-day spam rate, today, last 7 days, daily target, ready for outbound. |
| GET | /mailboxes/{email} | One mailbox. |
| POST | /mailboxes/{email} | Edit display name, daily cap (1-100) or time zone. |
| GET | /mailboxes/{email}/activity | The last 100 warm-up events: sent, received, replied, rescued from spam, errors. |
| POST | /mailboxes/{email}/pause | Pause warm-up. |
| POST | /mailboxes/{email}/resume | Resume warm-up. |
| POST | /mailboxes/{email}/test | Sign in now and report whether the stored login still works. |
| POST | /mailboxes/{email}/remove | Remove the mailbox and delete its stored login. Needs {"confirm": true}. |
Health
| Method | Endpoint | What it does |
|---|---|---|
| GET | /stats | Totals across your mailboxes: today and last 7 days, active and ready counts. |
| GET | /domains | SPF, DKIM selector, DMARC policy and MX for every connected domain. |
| GET | /tools/spf?domain= | SPF lookup for any domain. |
| GET | /tools/dkim?domain=&selector= | DKIM lookup: your selector, selectors seen in real mail, then 45 common ones. |
| GET | /tools/dmarc?domain= | DMARC record and policy for any domain. |
Outbound
| Method | Endpoint | What it does |
|---|---|---|
| GET | /campaigns | Your campaigns with status and stats. |
| POST | /campaigns | Create a draft: name, emails [{subject, body, wait_days}], mailboxes, daily_limit. Nothing is sent. |
| GET | /campaigns/{id} | One campaign: emails, mailboxes, stats, time left. |
| POST | /campaigns/{id} | Edit a draft or paused campaign; fields you leave out are kept. |
| GET | /campaigns/{id}/contacts | Contacts and where each is in the sequence (first 200). |
| POST | /campaigns/{id}/contacts | Add up to 1,000 contacts per call. Duplicates and unsubscribed addresses are skipped. |
| POST | /campaigns/{id}/start | Start or resume. Sends real email and uses credits ($2 per 1,000). Needs {"accept_sending_rules": true} the first time. If a picked mailbox is still warming it answers 400 with warming: true; send {"accept_warming_risk": true} only after the person agrees. Without credits it answers 402 with credits_required: true. |
| POST | /campaigns/{id}/pause | Pause. |
Domains & mailboxes
| Method | Endpoint | What it does |
|---|---|---|
| GET | /shop/domains | Domains you bought here, their hosted mailboxes, renewal date and price, plus the IMAP/SMTP settings. |
| GET | /shop/orders | Your domain orders and where each one is in setup. |
| GET | /shop/search?q=yourbrand | Available lookalike domains with the price for the first term and the renewal. |
| POST | /shop/checkout | Buy domains, with up to 3 mailboxes each: {"domains": [{"domain": "getacme.com", "mailboxes": [{"local": "john", "name": "John Tan"}]}], "accept_sending_rules": true}. Returns a Stripe checkout url; setup starts once it is paid. |
| POST | /shop/domains/{domain}/mailboxes | Add mailboxes to a domain you own: {"mailboxes": [{"local": "sarah", "name": "Sarah Lee"}]}. Returns a Stripe checkout url ($3 per mailbox per month). |
| GET | /shop/mailboxes/{email} | Login details (password, IMAP, SMTP) for one of your hosted mailboxes. |
| GET | /shop/domains/{domain}/dns | DNS records on a domain you own. |
| POST | /shop/domains/{domain}/dns | Add a record: {"type": "CNAME", "name": "www", "content": "cname.vercel-dns.com", "ttl": 600}. name is the subdomain, empty for the domain itself. Types: A, AAAA, CNAME, ALIAS, MX, TXT, CAA, SRV. |
| POST | /shop/domains/{domain}/dns/{id}/delete | Delete a record. Deleting the MX, SPF, DKIM or DMARC records stops your mailboxes working. |
Errors return {"error": "…"} with status 400, 401, 402 (out of credits: the body says how to pay; over the free mailbox limit a connect still answers 201 with needs_billing:true), 404, 409 or 429.
Paying: the person clicks once
An agent cannot pay. For extra mailboxes call POST /billing/checkout (monthly, or {"yearly": true}); for Outbound credits call POST /credits/checkout with {"usd": 10}, 25 or 100. Each returns a Stripe Checkout url for the account owner to open. Then poll GET /billing: subscription.active turns true, or credits_usd rises, as soon as Stripe confirms. The same three calls are the MCP tools create_billing_checkout, create_credits_checkout and get_billing_status.
MCP server
The same features as an MCP server, so an AI assistant can connect mailboxes, read warm-up health and run campaigns for you. Remote server, nothing to install. URL: https://app-emailwarmup.bobwork.ai/mcp, transport Streamable HTTP, auth with your API key.
Claude Code
claude mcp add --transport http email-warmup https://app-emailwarmup.bobwork.ai/mcp \ --header "Authorization: Bearer bwk_YOUR_KEY"
Cursor, Windsurf, VS Code and other clients (mcp.json)
{
"mcpServers": {
"email-warmup": {
"url": "https://app-emailwarmup.bobwork.ai/mcp",
"headers": { "Authorization": "Bearer bwk_YOUR_KEY" }
}
}
}Claude Desktop (claude_desktop_config.json, through the mcp-remote bridge)
{
"mcpServers": {
"email-warmup": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://app-emailwarmup.bobwork.ai/mcp", "--header", "Authorization: Bearer ${EW_KEY}"],
"env": { "EW_KEY": "bwk_YOUR_KEY" }
}
}
}Then ask things like "connect sales@mydomain.com with this app password", "which of my mailboxes are ready for outbound?" or "why is my spam rate up on hello@?".
MCP tools (39)
| Tool | What it does |
|---|---|
get_account | Your account: email, credit balance, free mailbox allowance (10, or 20 for accounts created before 27 October 2026, plus referral bonus), paid extras and your referral link. |
list_mailboxes | Every connected mailbox with warm-up day, status, 7-day spam rate, today's and last 7 days' numbers, and whether it is ready for outbound. |
get_mailbox | One mailbox's warm-up status and health. |
mailbox_activity | The last 100 warm-up events for a mailbox (sent, received, replied, rescued from spam, errors). |
warmup_stats | Totals across your mailboxes: today and last 7 days (sent, received, rescued, replied), active and ready counts. |
list_providers | IMAP/SMTP presets (Gmail app password, Yahoo, iCloud, Zoho, Lark, SES, SendGrid, Mailgun…) with hosts and ports, plus the Google and Zoho API routes. |
connect_imap_mailbox | Connect any mailbox with IMAP + SMTP. The login is tested before it is saved. Use an app password when two-factor sign-in is on. Give a preset (see list_providers) or the hosts. Warm-up starts the same day. |
connect_zoho_mailbox | Connect a Zoho Mail mailbox through the Zoho API (works on Zoho's free plan). Needs a Self Client id, secret and a generated code from api-console.zoho.com. |
google_connect_link | Get a link the user opens to connect Gmail / Google Workspace with Google sign-in (one click, any device). The mailbox appears in list_mailboxes a few minutes after they allow it. |
update_mailbox | Change a mailbox's display name, daily warm-up cap (1-100, null = default) or time zone (IANA, e.g. Europe/London). |
pause_mailbox | Pause warm-up for a mailbox. |
resume_mailbox | Resume warm-up for a mailbox. |
test_mailbox | Sign in to the mailbox now and report whether the stored login still works. |
remove_mailbox | Remove a mailbox and delete its stored login. Irreversible: ask the user first, then pass confirm=true. |
set_pool_mode | Shared network (default: warm with every mailbox on the service) or private pool (only your own mailboxes write to each other; needs 2+). |
domain_health | SPF, DKIM selector, DMARC policy and MX for every domain you have connected. |
check_spf | Look up a domain's SPF record. |
check_dkim | Find a domain's DKIM key: tries the selector you give, selectors seen in real mail, then 45 common ones. |
check_dmarc | Look up a domain's DMARC record and policy. |
get_credits | Prepaid credit balance, prices and recent charges (Outbound emails, AI drafts). |
list_campaigns | Your Outbound campaigns with status and stats. |
get_campaign | One campaign: its emails, mailboxes, stats and time left. |
create_campaign | Create a draft Outbound campaign (nothing is sent). Emails can use {first_name}, {company} and any contact field. Any connected mailbox can send; one that is still warming shows a warning first. |
update_campaign | Edit a paused or draft campaign. Fields you leave out keep their value. |
add_contacts | Add up to 1,000 contacts to a campaign. Each needs email; other fields (first_name, company…) fill the placeholders. Duplicates and unsubscribed addresses are skipped. |
list_campaign_contacts | Contacts in a campaign and where each is in the sequence (first 200). |
start_campaign | Start or resume a campaign. This SENDS real email and uses credits. Confirm with the user first. accept_sending_rules=true means the user agrees to https://emailwarmup.bobwork.ai/terms#outbound-beta (only people who may receive it, honest sender, unsubscribe honoured). If a chosen mailbox is still warming the call fails with warming:true; show the user the message and set accept_warming_risk=true only after they explicitly agree. Without credits it fails with credits_required:true: use create_credits_checkout. |
pause_campaign | Pause a running campaign. |
get_billing_status | Payment status after you gave the user a checkout link: credit balance, whether the extra-mailbox subscription is active, mailboxes vs the free limit, and checkouts still waiting for payment. Confirms a paid checkout straight away. |
create_billing_checkout | Get a Stripe Checkout url for extra mailboxes beyond the free limit (monthly, or yearly = 10 months' price for 12). The USER opens it and pays; you cannot. Then poll get_billing_status. Returns already:true when the account is subscribed. Prices come back in the result (prices). |
create_credits_checkout | Get a Stripe Checkout url to top up prepaid credits for Outbound sending and AI drafts (one-off $5, $10, $25 or $100; credits never expire). The USER opens it and pays; you cannot. Then poll get_billing_status. |
list_bought_domains | Domains bought in the domain shop, their hosted mailboxes, renewal date and price, plus IMAP/SMTP settings. |
search_domains | Find available lookalike domains for cold email, with first-term and renewal prices. |
buy_domains | Buy domains with up to 3 mailboxes each. Returns a Stripe checkout link for the person to pay; setup starts once paid. Needs accept_sending_rules true. |
add_hosted_mailboxes | Add mailboxes to a domain you bought here ($3 per mailbox per month). Returns a Stripe checkout link. |
hosted_mailbox_login | Password, IMAP and SMTP settings for one of your hosted mailboxes. |
list_dns_records | DNS records on a domain you bought here. |
add_dns_record | Add a DNS record to a domain you bought here. name = subdomain ('' for the domain itself). Types A, AAAA, CNAME, ALIAS, MX, TXT, CAA, SRV. |
delete_dns_record | Delete a DNS record by id (from list_dns_records). Deleting MX, SPF, DKIM or DMARC stops the mailboxes working. |
Limits and safety
- 120 requests per minute per key, up to 5 keys per account. Keys are stored hashed and can be revoked at any time.
- A key acts as its owner only: it sees and changes only your own mailboxes and campaigns, never anyone else's.
- Removing a mailbox needs an explicit confirm. Starting a campaign sends real email, uses credits and requires accepting the sending rules.
- The API and MCP are free. Warm-up is free up to 10 mailboxes (20 for accounts created before 27 October 2026), then $5 per mailbox per month ($3 each from 10 extra, $2 each from 50 extra)); Outbound emails cost $2 per 1,000 in prepaid credits.
FAQ
Is there a cost to use the API? No. The API and MCP server are free. You only pay for mailboxes above your free mailboxes, or for Outbound emails you choose to send.
Can I connect Outlook / Microsoft 365? Not yet: Microsoft requires OAuth for mailbox access, which is on the roadmap.
Does the API read my real email? No. Warm-up only touches its own warm-up emails. The optional Inbox feature is separate, opt-in, and not part of the API.
Where do I get help? Email info@bobwork.ai or use the Feedback page in the app.
Put the strategy to work
Connect a mailbox and the ramp starts today. Free for Gmail, Google Workspace, Zoho and Lark.