SHIPMAIL API: getting started
The SHIPMAIL API lets you manage domains, mailboxes, and email programmatically. Use the REST API directly or install an SDK for typed access. This guide covers setup, authentication, and common operations.
1. Create an API key
- Go to Settings > API Keys in your dashboard.
- Click Create API key.
- Give the key a descriptive name (e.g., "production", "staging", "local-dev").
- Copy the key immediately. It is shown only once.
- Store it securely: environment variable, secrets manager, or .env.local file (never commit to version control).
2. Make your first API call
- All API requests go to https://shipmail.to/api/v1.
- Authenticate with a Bearer token in the Authorization header.
- Try listing your domains: GET /v1/domains.
- The response includes a data array and pagination metadata.
3. Install an SDK (optional)
- TypeScript: npm install shipmail (or bun add shipmail). Works with Node.js 18+, Bun, and Deno.
- Python: pip install shipmail (or uv add shipmail). Requires Python 3.10+. Provides sync and async clients.
- Both SDKs are typed end-to-end and cover all API resources.
Code examples
List domains (curl)
curl https://shipmail.to/api/v1/domains \
-H "Authorization: Bearer YOUR_API_KEY"List domains (TypeScript SDK)
import Shipmail from "shipmail";
const client = new Shipmail({
apiKey: process.env["SHIPMAIL_API_KEY"],
});
const { data } = await client.domains.list();
console.log(data);List domains (Python SDK)
from shipmail import ShipMail
client = ShipMail("sm_live_...")
result = client.domains.list()
print(result["data"])Create a mailbox
const mailbox = await client.mailboxes.create({
domainId: "dom_abc123",
localPart: "support",
password: "secure-password-here",
displayName: "Acme Support",
});Send an email
const message = await client.messages.send({
mailboxId: "mbx_abc123",
to: [{ email: "customer@example.com", name: "Jane" }],
subject: "Your order has shipped",
text: "Hi Jane, your order #1234 is on its way.",
html: "<p>Hi Jane, your order #1234 is on its way.</p>",
});Set up a webhook
const webhook = await client.webhooks.create({
url: "https://yourapp.com/api/webhooks/shipmail",
events: ["message.received"],
});Key concepts
Authentication
Every request requires a Bearer token in the Authorization header. API keys are scoped to your account and have access to all domains and mailboxes.
Pagination
List endpoints use cursor-based pagination. The response includes a hasMore boolean and a cursor string. Pass the cursor as a query parameter to fetch the next page.
Idempotency
POST requests accept an Idempotency-Key header. If you retry a request with the same key within 24 hours, the API returns the original response without creating a duplicate resource.
Rate limits
Rate limits vary by plan. The API returns X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers on every response. When you hit the limit, the API returns 429 Too Many Requests.
Errors
Errors follow a consistent format with type, message, and code fields. HTTP status codes match standard conventions: 400 for bad input, 401 for missing auth, 404 for not found, 429 for rate limits.
Webhooks
Webhooks send POST requests to your URL when events occur (e.g., message.received). Each request includes a signature header for verification. Retry failed deliveries up to 5 times with exponential backoff.
Frequently asked questions
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. Everything the dashboard does, the API can do programmatically.
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. For high-volume sending, check your plan's monthly send limit (1,000 on Solo, 10,000 on Pro, 100,000 on Team).
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 SDK includes a webhooks.verify() helper for this.
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.