AI-native messaging API

Connect any AI to messaging in 60 seconds.

Paste one prompt into Claude, ChatGPT, or any LLM. It reads our API spec, creates your account, configures your domain, and sends your first email or WhatsApp message — all conversationally.

ChatGPT Actions Claude MCP Gemini Custom AI agents
The prompt

The one prompt that does everything

Copy this into Claude, ChatGPT, or any AI assistant. It handles the rest.

Paste into your AI
I want to set up Mail-o-Mail so I can send emails directly from this conversation. Read the API specification at: https://mail-o-mail.com/api/openapi.json This is a REST API. Base URL: https://mail-o-mail.com Authentication: Authorization: Bearer <API_KEY> (X-API-Key also accepted). You'll get the key during signup. Here's what I need you to do: 1. SIGN UP: Call POST /api/v1/ai-signup with my email address below. I'll give you the 6-digit verification code from my inbox. Then call POST /api/v1/ai-verify with the code to complete signup. This returns my API key — use it as an Authorization: Bearer header (X-API-Key also accepted) for all subsequent calls. 2. ADD MY DOMAIN: Call POST /api/v1/domains with my domain name. You'll get back DNS records (verification TXT, DKIM CNAMEs, SPF, DMARC) AND an auto_setup block. If auto_setup.supported is true, give me auto_setup.setup_url to click — I approve the records at my DNS provider (GoDaddy, Cloudflare, IONOS …) with one click and the domain verifies itself; GET /api/v1/domains/{domain}/auto-setup re-mints the link. Otherwise tell me exactly what to add to my DNS. After I confirm, call POST /api/v1/domains/{id}/verify to check verification. 3. ADD FROM-EMAIL: Call POST /api/v1/from-emails to add a sender address on my verified domain (e.g. [email protected]). 4. SEND A TEST: Call POST /api/v1/send to send me a test email confirming everything works. (An optional "consent" field is accepted on email sends: omit it to send as usual, but if you set it to no/false/0 the send is refused. Use it when sending to real recipients who opted in.) To send an email with a file attached, use POST /api/v1/send-attach instead — multipart/form-data with fields to, subject, body, from_email_id, and file (one file, max 10MB). 5. SHOW ME BULK: Explain how to run a campaign: - POST /api/v1/templates to create a template. DON'T put an unsubscribe link or compliance footer in the HTML — Mail-o-Mail appends its own at send time. The response returns template_number: use that everywhere a template is identified (send-template, send-to-tag, and GET/PATCH/DELETE /api/v1/templates/{template_number} to read the stored HTML back, fix a line in place, or delete it — a delete is refused while a sequence or scheduled campaign still uses it). - POST /api/v1/contacts/upload to upload contacts with a tag (an upsert: rows match existing contacts by email OR phone; omitted consent stays untouched on existing contacts; same-named custom fields are overwritten and the response counts them) - THE VARIABLE CONTRACT (guided send flow): GET /api/v1/templates/{template_number} first and read `variables` — the exact placeholders the template requires. Put those values on the contacts as custom fields with the SAME keys (upload_contacts / PATCH /api/v1/contacts). Then POST /api/v1/campaigns/send-to-tag to send to that tag: variables resolve per contact — core fields (email/phone/name/company), then the contact's custom fields by bare ; a core field wins over a same-named custom field when it is non-empty. A contact missing ANY required variable is SKIPPED — not sent, not charged — and named in skipped_missing_variables; tell me who was skipped and why. Only "on_missing_variables": "send_blank" sends to them with empty values, and only if I ask for it. - Explicit-recipients shape instead: POST /api/v1/send-template per recipient with every required variable in `variables` (a missing key fails by name: missing_variables) — never send a blank. - To send LATER instead of now, add "scheduled_at" to the same POST /api/v1/campaigns/send-to-tag body — ISO 8601 WITH an explicit UTC offset (e.g. 2026-09-10T09:00:00+05:30), at least 5 minutes and at most 90 days ahead (not with send_mode intelligent). Run it with "dry_run": true first and show me the time and the numbers; they are a projection — who receives it, who is skipped and what it costs are resolved when it fires, and credits move only then. GET /api/v1/campaigns/scheduled lists what is scheduled; POST /api/v1/campaigns/scheduled/{scheduled_id}/cancel cancels a pending one (no confirmation needed — cancelling prevents a send). There is no edit: cancel, then schedule again. - GET /api/v1/campaigns/{id}/status to track delivery (skipped rows show as skipped_missing_variables with their missing names) 6. WHATSAPP (optional): I can also send WhatsApp messages. - GET /api/v1/whatsapp/status to check if my WhatsApp is connected. - Connecting WhatsApp needs ME in a browser (Meta Embedded Signup), but you can start it: POST /api/v1/whatsapp/connect-intents returns a connect_url — hand it to me, then poll GET /api/v1/whatsapp/connect-intents/{token} every 30-60 seconds until it's completed. When it completes, ASK me whether I want a webhook set up so my own systems receive incoming WhatsApp messages: if yes, agree the HTTPS URL with me, then POST /api/v1/whatsapp/webhook — the response shows the signing secret ONCE, so relay it to me immediately. Prove it works with POST /api/v1/whatsapp/webhook/test, and debug with GET /api/v1/whatsapp/webhook/deliveries. - GET /api/v1/whatsapp/templates to list my templates (only APPROVED ones can be sent; components come back as a parsed object), or POST /api/v1/whatsapp/templates to create one and submit it to Meta for approval — buttons are a typed union (QUICK_REPLY{text} | URL{text,url [,example]} | PHONE_NUMBER{text,phone_number}); for an image/video/ document header first call POST /api/v1/whatsapp/media with purpose "template_header" (base64 or a public https url) and pass the returned header_handle. The template also appears in my dashboard. Poll GET /api/v1/whatsapp/templates/{name}/status for approval. - POST /api/v1/whatsapp/media with purpose "send_media" hosts an image/video/pdf publicly (quota-limited, removed after 30 days if no send used it) and returns the url for a media-header send. - POST /api/v1/whatsapp/send-template to send an approved template to a phone number. Consent: with "consent" omitted the STORED contact's consent decides (stored no → no_consent, unknown contact → consent_unknown); pass "consent": "yes" only when the person opted in. - POST /api/v1/whatsapp/send-message to send FREE-FORM text (optionally up to 3 quick-reply buttons) WITHOUT a template — only allowed within 24 hours of the customer's last message to me (WhatsApp's customer-service-window rule). Outside the window it refuses with 422 window_closed and nothing is sent — fall back to send-template then. - GET /api/v1/whatsapp/stats for delivery and read statistics, and POST /api/v1/whatsapp/send-otp to deliver one-time passcodes (I generate and verify the code — Mail-o-Mail only delivers it). 7. AUTOMATE (optional): I can also set up Triggers — keyword-based auto-replies for web chat and WhatsApp (e.g. STOP, PRICE, ORDER STATUS) that confirm with Yes/No, reply with a message, or call my own API. Triggers are built and managed from the dashboard, not this API — there's no endpoint for creating one yet. If I ask about automations, explain what Triggers can do and send me to https://mail-o-mail.com/triggers to build one visually. 8. SEQUENCES (optional): I can also build automated drip sequences — multi-step flows that enroll a contact and message them over time. - GET /api/sequences to list mine, or POST /api/sequences to create one (name + entry tag). A flow is a chain of nodes — message, confirm, condition, wait, email, api_call, update_consent_no, and end — so it can branch, pause, honor opt-outs, and send across channels. Creating a sequence only saves it as a draft; nothing sends until it's turned on. - POST /api/sequences/{id}/status with {"status": "active"} to turn it on (or "inactive" to pause it). Activating needs the Triggers add-on enabled on the account — if it isn't, the call comes back addon_required and I should point the user at Admin → Home to enable it. - POST /api/sequences/{id}/enroll to add one contact — by contact_id, email, or phone (whichever I have). - GET /api/sequences/{id}/executions to see who's enrolled, what step they're on, and how each run finished. In short: create it, turn it on, enroll — all from your assistant. 9. MANAGE MY CONTACTS: full single-contact CRUD. Identify a contact by email and/or phone — never an internal id. - POST /api/v1/contacts to create one (name, company, tags, consent yes/no, custom fields). The response says honestly whether it was "created" or "merged" into an existing contact with that email/phone. POST /api/v1/contacts/batch takes up to 20 at once (per-item results). - PATCH /api/v1/contacts to update — changes go in a "set" object (name, company, email, phone, custom; a null custom value deletes that key). If a new email/phone collides with another contact it answers would_merge — ask me before repeating with "merge": true. - POST /api/v1/contacts/tags to tag one contact (missing tags are auto-created); DELETE /api/v1/contacts/tags to untag one. Tag management: POST /api/v1/tags/rename (merge:true folds a tag into an existing same-named one), DELETE /api/v1/tags (refused while a sequence or scheduled campaign uses it), POST /api/v1/tags/retag to apply a tag to everyone carrying another tag. POST /api/v1/contacts/consent/bulk flips consent for up to 1,000 listed contacts or a whole tag — confirm with me first. GET /api/v1/contacts/stats and GET /api/v1/contacts/detail for engagement + the full record; GET /api/v1/contacts/messages for their last chat messages. - POST /api/v1/contacts/consent/enable or /disable to flip marketing consent — auditable, and the response is honest: consent yes with an active unsubscribe still can't be emailed (sends_allowed: false). - DELETE /api/v1/contacts erases the contact AND their chat history — confirm with me first. Unsubscribes always survive a delete, so a removed address can never be accidentally re-mailed. BEFORE A BIG SEND (verify, then confirm — never guess): - PREVIEW: POST /api/v1/campaigns/preview with the template_number and one real contact's email — it renders the email exactly as the send will (same renderer), returns which resolved and which came out blank, and costs nothing. Show me the subject and the unresolved list. - AUDIENCE: GET /api/v1/contacts/by-tag?tag={name} (or tag_id) lists who carries the tag with consent, suppression and sendable flags plus honest totals. Tag names match case-insensitively and trimmed, whole name only; an unknown tag is tag_not_found, an empty one is tag_empty. - NUMBERS: POST /api/v1/campaigns/send-to-tag with "dry_run": true returns the resolved recipient_count, credits_required, without_consent and suppressed counts without sending. Show me those numbers and wait for my explicit yes before the real send. - GET /api/v1/credits to check my balance first — 1 credit = 1 email or 1 WhatsApp message. Warn me if the campaign needs more than I have. - GET /api/v1/recommendations/send-time?tag_id={id} tells you that audience's best send window, computed from their last 90 days of email opens, and GET /api/v1/recommendations/segment?tag_id={id} ranks the tag's most-engaged contacts. Both are advisory — show me the summary and let me decide. They say so honestly when there isn't enough data. - To deliver at each recipient's personal best time, pass "send_mode": "intelligent" to POST /api/v1/campaigns/send-to-tag. PREPARE RECIPIENTS FOR A CAMPAIGN: - Call GET /api/v1/templates/{template_number}/sample-excel to get a download_url for a fillable spreadsheet. Its columns are exactly what that template needs (phone, consent, plus any body variables, media_url for a media header, and a dynamic-URL-button column). Give me the download_url so I can open it, fill it with my contacts, and upload it when sending the campaign. The link expires in about an hour — fetch a fresh one if needed. MANAGING MY CONNECTION: - CHECK: call GET /api/v1/whoami any time to confirm which account this key is connected to (org, email, credits, WhatsApp status). - DISCONNECT: call POST /api/v1/disconnect to disconnect this account, then forget my API key. (Pass {"rotate_api_key": true} to hard-revoke the key everywhere — it returns a new key.) - RECONNECT: ask me for my API key again (I can get it from my dashboard) and verify it with GET /api/v1/whoami, or run the signup steps above for a new account. Let's start! My email is: [YOUR EMAIL HERE]

No account needed beforehand. Your AI creates your Mail-o-Mail account during the conversation via the signup API. Works with any AI that can make HTTP calls.

Process

How it works

Your AI reads our OpenAPI spec and knows every endpoint, parameter, and workflow.

1

Paste the prompt

Copy the prompt above into Claude, ChatGPT, or any AI assistant. Replace [YOUR EMAIL HERE] with your email. The AI reads our API spec at /api/openapi.json and understands every endpoint.

2

Your AI sets up your account

The AI calls our signup endpoint, sends you a verification code, activates your account, and gets your API key. Then it walks you through adding your domain (with exact DNS records to copy) and setting up your sender address — all in conversation.

3

Send messages by talking

"Send a newsletter to my VIP customers about our spring sale." Your AI creates the template, uploads contacts, tags them, sends the campaign, and reports back with delivery stats. No dashboard needed.

Examples

Just talk to your AI

You
Send a quick email to [email protected] letting her know the proposal is ready. Use my work email.
AI
Done! I called POST /api/v1/send from your verified address [email protected]. Sarah should receive it within seconds. Subject: "Your proposal is ready."
You
I have 2,000 contacts for a holiday sale. Create a campaign and send it to all of them.
AI
Here's my plan:

1. POST /api/v1/templates — create a holiday sale template
2. POST /api/v1/contacts/upload — upload all 2,000, tagged "holiday-2025"
3. POST /api/v1/campaigns/send-to-tag — send to the tag
4. GET /api/v1/campaigns/{id}/status — track delivery

That'll use 2,000 credits ($2.00). Want me to proceed?
You
A customer on WhatsApp asked if we ship to Pune. Tell them yes, 3-day delivery, and let them confirm the order with one tap.
AI
They messaged you 2 hours ago, so the 24-hour WhatsApp reply window is open — no template needed. I called POST /api/v1/whatsapp/send-message with your answer and two quick-reply buttons: "Confirm order" and "Not now". The reply is in your chat console conversation too. Once the window closes, I'd switch to an approved template via POST /api/v1/whatsapp/send-template.
You
A customer just asked "do you have a trigger for order status?" What should I tell them?
AI
Triggers are built and managed from your dashboard, not this API. Head to /triggers, add the keyword ORDER STATUS, confirm with Yes/No, then call your own order-status API and reply with its result. I can walk you through the flow builder step by step.
Capabilities

What your AI can do

Every capability below is a REST API endpoint your AI calls directly.

Email WhatsApp Sequences Live chat + keyword triggers in the dashboard
🚀

Account setup

Create and configure your account entirely through conversation. No forms, no dashboard.

  • →Sign up with email verification
  • →Register and verify sending domains
  • →Add sender email addresses
  • →Check account setup status
📧

Send messages

Single emails, template-based emails and WhatsApp messages, or bulk campaigns to thousands of contacts.

  • →Send custom HTML emails
  • →Send using saved templates with variables
  • →Run bulk campaigns to tagged contacts
  • →Track delivery, opens, and clicks
📋

Manage everything

Templates, contacts, tags, domains, and credits — all via API.

  • →Create and list message templates
  • →Upload contacts (JSON or CSV)
  • →Organize contacts with tags
  • →Check credit balance
🔁

Automate sequences

Drip sequences your AI creates, activates, and enrolls contacts into — no dashboard needed. Create it, turn it on, enroll — all from your assistant.

  • →Create multi-step drips (email, chat, waits, branches)
  • →Activate or pause a sequence
  • →Enroll contacts by id, email, or phone
  • →Inspect who's in a sequence and where
Compatible with

Works with any AI

💬 ChatGPT
🟠 Claude
💎 Gemini
🔧 Cursor / Windsurf
🤖 Custom AI agents

🟠 Claude — native MCP server

Connect Mail-o-Mail as a real MCP server: a hosted endpoint at mail-o-mail.com/api/mcp for Claude Code and other MCP clients, or a one-file local server for Claude Desktop. 75 tools, WhatsApp and sequences included.

Claude setup guide →

💬 ChatGPT — Custom GPT

Build your own private GPT on our Actions spec in about two minutes: import one URL, paste your API key, and ChatGPT can run every capability — campaigns, WhatsApp, sequences, recommendations.

ChatGPT setup guide →
Machine-readable

API specification

Point your AI or developer tools at our OpenAPI specification for full endpoint documentation.

Your AI is ready to send messages.

Copy the prompt, paste it into your AI, and watch it set everything up for you.

Copy the prompt