Quick start

From zero to sending email in 5 minutes. This guide covers the minimum steps to get a working setup through the API.

Last updated

1. Get your API key

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

export SHIPMAIL_API_KEY="sm_live_..."

2. Add a domain

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

curl

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

TypeScript

import ShipMail from "shipmail"; const shipmail = new ShipMail(process.env.SHIPMAIL_API_KEY); const domain = await shipmail.domains.create({ name: "example.com" }); console.log(domain.id); // dom_...

Python

from shipmail import ShipMail client = ShipMail("sm_live_...") domain = client.domains.create({"name": "example.com"}) print(domain["id"]) # dom_...

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

Alternative: Register a domain

Instead of bringing your own domain, you can search for and register one directly through shipmail. DNS records are configured automatically, so you can skip steps 3 and 4.

TypeScript

// Search for available domains const { results } = await shipmail.domains.search({ keyword: "mycompany" }); const available = results.filter((r) => r.available); // Register a domain (charges your saved payment method) const domain = await shipmail.domains.register({ name: "mycompany.com", contact: { first_name: "Jane", last_name: "Doe", address1: "123 Main St", city: "San Francisco", state: "CA", zip: "94105", country: "US", phone: "+14155551234", email: "jane@example.com", }, }); // Domain is registered, DNS is configured automatically

Python

# Search for available domains result = client.domains.search({"keyword": "mycompany"}) available = [r for r in result["results"] if r["available"]] # Register a domain (charges your saved payment method) domain = client.domains.register({ "name": "mycompany.com", "contact": { "first_name": "Jane", "last_name": "Doe", "address1": "123 Main St", "city": "San Francisco", "state": "CA", "zip": "94105", "country": "US", "phone": "+14155551234", "email": "jane@example.com", }, }) # Domain is registered, DNS is configured automatically

3. Configure DNS

Add the 4 DNS records (MX, SPF, DKIM, DMARC) to your DNS provider. The records are returned in the domain creation response and are visible in your dashboard under the domain row.

See the domain setup guide for details on each record and provider-specific notes.

4. Verify the domain

shipmail automatically polls your DNS records every 30 seconds. Once all 4 pass, the domain status changes to verified. You can also trigger verification manually:

curl

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

TypeScript

const result = await shipmail.domains.verify(domain.id); console.log(result.all_verified); // true

Python

result = client.domains.verify(domain["id"]) print(result["all_verified"]) # True

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.

TypeScript

// 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

Python

# 1. Create a webhook for domain events webhook = client.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 domain = client.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 the webhooks guide for payload details and signature verification.

5. Create a mailbox

Create a mailbox on your verified domain.

curl

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" }'

TypeScript

const mailbox = await shipmail.mailboxes.create({ domain_id: domain.id, address: "hello", display_name: "Hello", }); console.log(mailbox.id); // mbx_...

Python

mailbox = client.mailboxes.create({ "domain_id": domain["id"], "address": "hello", "display_name": "Hello", }) print(mailbox["id"]) # mbx_...

6. Send an email

Send your first email from the mailbox you just created.

curl

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." }'

TypeScript

const message = await shipmail.messages.send({ from: "hello@yourdomain.com", to: ["recipient@example.com"], subject: "Hello from shipmail", text: "It works.", }); console.log(message.id); // msg_...

Python

message = client.messages.send({ "from": "hello@yourdomain.com", "to": ["recipient@example.com"], "subject": "Hello from shipmail", "text": "It works.", }) print(message["id"]) # msg_...

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.
  • Connect an email client to read and send from your mailbox directly.

Frequently asked questions

How long does the full setup take?

Most people finish in about 10 minutes. Adding the domain and creating a mailbox takes a minute or two. DNS propagation is the slowest step, usually a few minutes, occasionally longer depending on the provider.

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, then follow the domain setup 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.