Domains
Add your own domains so mailboxes can send and receive email. Each domain needs DNS records verified before it becomes active.
The domain object
{
"object": "domain",
"id": "dom_abc123",
"name": "example.com",
"status": "verified",
"managed_by": "external",
"dns_provider": "cloudflare",
"mx_verified": true,
"spf_verified": true,
"dkim_verified": true,
"outbound_verified": true,
"catch_all_mailbox_id": null,
"verified_at": "2025-01-15T10:30:00.000Z",
"created_at": "2025-01-15T10:00:00.000Z",
"updated_at": "2025-01-15T10:30:00.000Z"
}Create a domain
POST /v1/domainsScope: domains:write. Rate limit tier: write.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Domain name, e.g. example.com. Max 253 characters. |
Example
curl -X POST https://shipmail.to/api/v1/domains \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{"name": "example.com"}'Returns the domain object with status 201.
List domains
GET /v1/domainsScope: domains:read. Rate limit tier: read. Supports cursor and limit pagination parameters.
Retrieve a domain
GET /v1/domains/:idScope: domains:read. Returns the domain object or 404.
Update a domain
PATCH /v1/domains/:idScope: domains:write. Rate limit tier: write.
Request body
| Field | Type | Description |
|---|---|---|
| catch_all_mailbox_id | string | null | Set to a mailbox ID to enable catch-all, or null to disable. |
Delete a domain
DELETE /v1/domains/:idScope: domains:write. Returns 204 with no body on success. Deleting a domain also removes its mailboxes and DNS configuration.
Verify a domain
POST /v1/domains/:id/verificationScope: domains:read. Rate limit tier: verification (1 request per minute). Triggers an immediate DNS verification check and returns the updated domain object.
For automated setups, you can subscribe to the domain.verified and domain.verification_failed webhook events instead of polling this endpoint.
Managed vs external domains
Every domain has a managed_by field indicating how DNS is managed.
external— you manage DNS yourself at your own provider. You must add the required records manually and verify them.namecom— the domain was registered through shipmail. DNS records are configured automatically.
Search domains
POST /v1/domains/searchScope: domains:read. Rate limit tier: read. Search for available domain names to register through shipmail. Returns availability and pricing.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| keyword | string | Yes | Keyword to search for available domains. |
Example
curl -X POST https://shipmail.to/api/v1/domains/search \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{"keyword": "mycompany"}'Returns an object with a results array. Each result includes domain_name, available, purchase_price, renewal_price, and currency.
Register a domain
POST /v1/domains/registerScope: domains:write. Rate limit tier: write. Register a domain through shipmail. Charges the saved payment method and returns the created Domain object. Requires an active subscription. DNS records are configured automatically.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Domain name to register, e.g. example.com. |
| years | integer | No | Registration period in years (1-10). Defaults to 1. |
| contact | object | Yes | Registrant contact information: first_name, last_name, address1, address2, city, state, zip, country (ISO 3166-1 alpha-2), phone (E.164), email. |
Example
curl -X POST https://shipmail.to/api/v1/domains/register \
-H "Authorization: Bearer sm_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "mycompany.com",
"years": 1,
"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"
}
}'Returns a Domain object (201). The domain is created with managed_by: "namecom" and DNS records are configured automatically. Returns 402 if payment fails, 403 if no active subscription.