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 automaticallyPython
# 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 automatically3. 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); // truePython
result = client.domains.verify(domain["id"])
print(result["all_verified"]) # TrueAlternative: 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 passPython
# 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 passThe 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.