Email API
Send and receive email from your own domain over the API: verified-domain onboarding, DKIM signing, delivery and suppression tracking.
Overview
The Email API sends and receives email from a domain you own. You verify the domain once (we generate its DKIM key and the DNS records to publish), then send over the API and, optionally, receive mail at addresses on that domain.
Base path: https://api.callmissed.com/api/v1/email
Authentication uses your existing CallMissed API key, the same cm_ key you use for every other API. The key needs the email permission enabled (toggle it on the API keys page). No separate email key.
Read this before you write your first send. Verification registers exactly one sender username on the domain,
donotreply, sodonotreply@your-domainalways works. Any other local part on a verified domain has to be registered as a sender first: either up front withPOST /api/v1/email/domains/{domain_id}/senders, or implicitly, because the send path registers thefromlocal part on its first refusal and retries. Registration is eventually consistent, so a send from a brand-new sender can still come back as503 sender_propagating, meaning retry shortly and nothing else is needed. See Sender Addresses.
- 1
Your app
Add a domain, publish the DNS records we generate
- 2
CallMissed
Verify ownership, SPF and both DKIM records, then accept sends from that domain
- 3
Recipients
Receive DKIM-signed mail from your own domain
Billing: Email is fully credit-based. Every send is charged to your credit balance at 30 credits (₹30) per 1,000 emails (per recipient), the same wallet as every other API. There is no separate email invoice. Full detail: Pricing.
The pages in this section
End to end in three calls
Every request below uses the real base URL and the real auth header. Replace cm_your_key with your key and acme.com with your domain.
# 1. Register the domain - the response carries the DNS records to publish
curl -X POST https://api.callmissed.com/api/v1/email/domains \
-H "Authorization: Bearer cm_your_key" \
-H "Content-Type: application/json" \
-d '{"domain": "acme.com"}'
# 2. After publishing every required record, verify it (repeat until verified is true)
curl -X POST https://api.callmissed.com/api/v1/email/domains/9d0f8b3a-1c2e-4a5b-8f7d-6e2a1b0c9d4e/verify \
-H "Authorization: Bearer cm_your_key"
# 3. Send
curl -X POST https://api.callmissed.com/api/v1/email/send \
-H "Authorization: Bearer cm_your_key" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme Ops <donotreply@acme.com>",
"to": ["Ada <customer@example.com>"],
"subject": "Your receipt",
"text": "Thanks for your order.",
"html": "<p>Thanks for your order.</p>",
"reply_to": "support@acme.com"
}'A successful send returns 202 Accepted:
{
"id": "9d0f8b3a-1c2e-4a5b-8f7d-6e2a1b0c9d4e",
"message_id": "<1a2b3c4d@acme.com>",
"messageId": "<1a2b3c4d@acme.com>",
"messageIds": ["<1a2b3c4d@acme.com>"],
"status": "sent",
"suppressed": ["blocked@example.com"]
}Field-by-field detail for that body is on Send Email.
When a call fails
Error bodies come in four shapes and they are not interchangeable, so branch on the HTTP status first, then check whether detail is an object, a string or an array before reaching for reason. The shapes, the full reason table, and the three sending ceilings are on Limits, Quotas & Errors.
Two failures dominate the first send. 403 domain_not_verified means the domain has not passed all four DNS checks yet. 503 sender_propagating means the from address was just registered as a sender and the mail service has not finished propagating it, so retry shortly. Both are covered on Sender Addresses.