Quick start
From zero to sending email in 5 minutes. This guide covers the minimum steps to get a working setup through the API.
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.