Skip to content

StartAPI quick start

API quick start

From zero to sending email through the API in 5–10 minutes. Six calls: create a key, add a domain, publish DNS, verify, create a mailbox, send. DNS propagation is the only step you wait on.

Last updated

1. Get your API key

Go to Developer > API keys in your dashboard and create a new key. Copy it immediately. It is only shown once.

export SHIPMAIL_API_KEY="sm_live_..."

Keys are scoped. For this walkthrough the key needs domains:write, mailboxes:write and messages:send. See Authentication for the full list.

2. Add a domain

Register the domain you want to send and receive email on.

curl -X POST https://shipmail.to/api/v1/domains \
  -H "Authorization: Bearer $SHIPMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "example.com"}'

The response includes the DNS records you need to add. Save these for the next step.

3. Configure DNS

Retrieve the DNS record set, then add the 6 records to your DNS provider. The set includes MX, SPF, DKIM, and DMARC plus two custom MAIL FROM records for outbound alignment.

curl https://shipmail.to/api/v1/domains/DOMAIN_ID/dns-records \
  -H "Authorization: Bearer $SHIPMAIL_API_KEY"

See DNS records explained for what each record does and DNS setup by provider for where to paste them.

4. Verify the domain

Shipmail automatically polls the 4 activation records every 30 seconds. Once they pass, the domain status changes to verified. The DNS records endpoint reports live status for the full 6-record set. You can also trigger activation verification manually:

curl -X POST https://shipmail.to/api/v1/domains/DOMAIN_ID/verification \
  -H "Authorization: Bearer $SHIPMAIL_API_KEY"

Alternative: use a webhook instead of polling

If you are automating domain setup, subscribe to the domain.verified event instead of polling the verification endpoint. Create a webhook before adding your domain, then continue your setup when the event fires.

// 1. Create a webhook for domain events
const webhook = await shipmail.webhooks.create({
  url: "https://yourapp.com/api/webhooks/shipmail",
  events: ["domain.verified", "domain.verification_failed"],
});
// Save webhook.secret for signature verification

// 2. Add the domain
const domain = await shipmail.domains.create({ name: "example.com" });

// 3. Add DNS records at your provider, then wait for the webhook
// shipmail sends a domain.verified event when all records pass

The webhook payload includes the domain_id and verified_at timestamp. See webhooks for payload details and signature verification.

5. Create a mailbox

Create a mailbox on your verified domain.

curl -X POST https://shipmail.to/api/v1/mailboxes \
  -H "Authorization: Bearer $SHIPMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain_id": "DOMAIN_ID",
    "address": "hello",
    "display_name": "Hello",
    "password": "UniqueSecret123"
  }'

6. Send an email

Send your first email from the mailbox you just created.

curl -X POST https://shipmail.to/api/v1/messages \
  -H "Authorization: Bearer $SHIPMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "hello@yourdomain.com",
    "to": ["recipient@example.com"],
    "subject": "Hello from Shipmail",
    "text": "It works."
  }'

Next steps

  • Set up webhooks to receive notifications when email arrives or bounces.
  • Use the TypeScript or Python SDK for type-safe access to the full API.
  • Try requests without sending real mail in sandbox mode.
  • Give an AI agent the same mailbox through the MCP server.

Frequently asked questions

How long does the full setup take?

Account and mailbox setup takes about 3 minutes. Most domains can send 5–10 minutes after setup, depending on DNS propagation; some providers can take longer.

Do I need my own domain to send email?

Yes. You send from a mailbox on a domain you own and have verified. If you do not have a domain yet, register one at any registrar or through the API, then follow the domain steps.

I am not a developer. Can I still use Shipmail?

Yes. You can create mailboxes, read, and send email entirely from the dashboard and a regular email client like Apple Mail or Outlook. The API is optional and only needed if you want to send programmatically.

Is the API key safe to put in my code?

Never commit API keys to a public repository or ship them in client-side code. Store the key in a server-side environment variable (for example SHIPMAIL_API_KEY) and read it at runtime. Rotate the key from the dashboard if it leaks.

What can I do with the API?

Manage domains, create and delete mailboxes, send email, retrieve messages and threads, and configure webhooks for inbound email processing. Newsletters, calendars, automations and team members have endpoints too. Billing and domain purchase stay in the dashboard.

Is there a rate limit?

Yes. Rate limits depend on your plan. The API returns rate limit headers on every response so you can monitor usage. If you hit the limit, wait for the reset window indicated in the X-RateLimit-Reset header.

Can I use the API for transactional email?

Yes. Use the messages.send endpoint to send transactional email from any of your mailboxes. Regular sends are pooled across your organization: Solo includes 20,000 per month, Pro 40,000, and Team 120,000. New organizations also follow a gradual daily ramp and reputation controls.

Which languages are supported?

TypeScript and Python. The TypeScript SDK works with Node.js 18+, Bun, and Deno. The Python SDK supports 3.10+ with both sync and async clients. You can also use the REST API directly from any language.

How do I verify webhook signatures?

Each webhook request includes a signature in the X-Shipmail-Signature header. Compute an HMAC-SHA256 of the raw request body using your webhook secret and compare it to the signature. The TypeScript SDK exports a standalone verifyWebhook() function that does this for you.

Where can I find the full API reference?

The complete API reference is at shipmail.to/docs/api. The OpenAPI specification is available at shipmail.to/openapi.json for code generation and import into tools like Postman.