Skip to main content

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, so donotreply@your-domain always works. Any other local part on a verified domain has to be registered as a sender first: either up front with POST /api/v1/email/domains/{domain_id}/senders, or implicitly, because the send path registers the from local part on its first refusal and retries. Registration is eventually consistent, so a send from a brand-new sender can still come back as 503 sender_propagating, meaning retry shortly and nothing else is needed. See Sender Addresses.

  1. 1

    Your app

    Add a domain, publish the DNS records we generate

  2. 2

    CallMissed

    Verify ownership, SPF and both DKIM records, then accept sends from that domain

  3. 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.