1. Get Started
  • Welcome to the Cold Mail Reseller API
  • Get Started
    • Overview
    • Authentication
    • Quick Start
  • Core Concepts
    • Users
    • Domains
    • DNS Management
    • Subscriptions
    • Pre-Warmup
    • Domain Renewal
    • Mailbox Warmup
    • OAuth Exports
    • Platform Exports
    • Mailboxes
    • Sandbox API
    • 1+ Year Subscriptions
  • API Reference
    • Users
      • List Users
      • Get User
      • Create User
      • Update User
      • Delete User
    • Geo
      • List Countries
      • List States
    • Domains
      • Domain Renewal
        • Get Domain Renewal Prices
        • Renew Domains
        • Toggle Domain Auto-Renew
      • Get Domain
      • List Available Aged Domains
      • Order Aged Domains
      • Get Domains by User
      • Check Domain Availability
      • Check Single Domain Availability
      • Check Workspace Existence
      • Set Domain Forwarding
      • Set Email Forwarding
      • Delete Domains
    • DNS
      • Get DNS Records
      • Add DNS Records
      • Update DNS Record
      • Update Nameservers
      • Delete DNS Record
    • Mailboxes
      • List Mailboxes
      • Get Mailboxes by User
      • Get Mailbox
      • Get Admin Mailbox Details
      • Update Mailbox Details
      • Delete Mailbox
    • Mailbox Warmup
      • Add Warmup to Mailbox
      • Toggle Warmup
      • Update Warmup Settings
      • Delete Warmup Subscription
    • Orders
      • Get Order Status
      • Get Order Details
      • Create Order
      • Create Order (JSON)
      • Create Mailbox Order (JSON)
      • Process Order
    • Subscriptions
      • 1+ Year Subscription
        • Recreate Subscription
      • Get Subscriptions
      • Renew Subscriptions
      • Cancel Subscription
      • Toggle Auto-Renewal
    • Exports
      • Platform Exports
        • Get Platform Credentials
        • Get Platform Workspaces
        • Add Platform Credential
        • Export Mailboxes to Platform
        • Update Platform Credential
        • Remove Platform Credential
      • OAuth Exports
        • Perform OAuth
        • Add Client ID to Domains
    • Pre-Warmup
      • Sandbox
        • Get Sandbox Pre-warmup Domains
        • Order Sandbox Pre-warmup
        • Reset Sandbox Pre-warmup
      • Get Pre-warmup Domains
      • Order Pre-warmup
    • Placement Test
      • Create Placement Order
      • Get Placement Reports
  • Resources
    • Errors
    • Rate Limits
    • Pagination
    • Sandbox
    • MCP
  • Webhooks
    • Overview
    • Events
      • DNS Events
      • Subscription Events
      • Prewarmup Events
      • Mailbox Warmup Events
      • Mailbox Events
      • Domain Events
  • Schemas
    • Error
    • Success
    • MessageResponse
    • User
    • Domain
    • ErrorResponse
    • Mailbox
    • Subscription
    • DnsRecord
    • Error Response
    • Pagination Meta
    • Action Error Response
    • PrewarmupOrderResult
    • OrderCreationResult
  1. Get Started

Quick Start

Go from zero to a fully provisioned domain and mailboxes.

This guide walks through the complete flow (i.e, creating a user, checking availability, placing an order, and handling the webhook).


Before You Start

INFO

You need a CMR partner API key before making any requests. Sign up and generate one at https://partners.coldmailreseller.com.

You'll also need a publicly reachable webhook URL to receive the order confirmation. If you're testing locally, use a tool like ngrok to expose a local port — or use the Sandbox to test the full flow without a live endpoint.


How the Order Flow Works

Create user   →   Check availability   →   Place order
                                                 ↓
                                         { orderId: "ord_..." }
                                                 ↓
                                          10–90 seconds
                                                 ↓
                                  domain.order.success  ✓
                                                 ↓
                                  mailbox.order.success ✓
                                                 ↓
                              mailbox.created (one per mailbox)

You can also poll GET /orders/status?userId=&orderId= at any point instead of (or alongside) listening for webhooks.

The HTTP 200 on the order request confirms it was accepted — not completed. Wait for mailbox.created events before treating the order as done.


Step 1 — Create a User

Every domain and mailbox in CMR belongs to a user. Create one first and store the returned id — you'll pass it as userId on every subsequent request for this customer.

POST /users HTTP/1.1
cmr-x-api-key: your_partner_api_key
Content-Type: application/json

{
  "email": "alice@company.com",
  "firstName": "Alice",
  "lastName": "Johnson",
  "company": "Acme Corp",
  "languagePreference": "en",
  "addressLineOne": "123 Main Street",
  "city": "New York",
  "state": "New York",
  "country": "US",
  "postalCode": "10001",
  "phoneCc": "1",
  "phone": "2125551234"
}

Response:

{
  "status": 200,
  "message": "User created",
  "data": { "id": "usr_abc123" }
}

Save data.id as userId.


Step 2 — Check Domain Availability

Always check availability before placing an order. Attempting to register an unavailable domain results in a failed order.

```http POST /domains/available-single HTTP/1.1 cmr-x-api-key: your_partner_api_key Content-Type: application/json

{ "domainName": "alicesender.com", "years": 1 }


:::warning
Both `domainName` and `years` are required. A body like `{ "domain": "alicesender.com" }` (wrong key, missing `years`) returns `422 Unprocessable Entity`.
:::

**Response:**
```json
{
  "status": 200,
  "message": "Domain availability status",
  "data": {
    "status": "AVAILABLE",
    "domainName": "alicesender.com",
    "domainPrice": "12.99",
    "renewPrice": "14.99"
  }
}
`POST /domains/available` checks **one base name across multiple TLDs** — it does not take a list of full domain names. To check several unrelated full domain names, call `/domains/available-single` once per domain instead.
POST /domains/available HTTP/1.1
cmr-x-api-key: your_partner_api_key
Content-Type: application/json

{
  "domainName": "alicesender",
  "tlds": ["com", "io", "net"],
  "years": 1
}

Note domainName here is the base name without a TLD (e.g. alicesender, not alicesender.com).

Response:

{
  "status": 200,
  "data": {
    "availableDomains": [
      { "status": "AVAILABLE", "domainName": "alicesender.com", "domainPrice": "12.99", "renewPrice": "14.99" },
      { "status": "UNAVAILABLE", "domainName": "alicesender.io", "domainPrice": "9.99", "renewPrice": "11.99" }
    ],
    "restrictedDomains": []
  }
}

Filter for status: "AVAILABLE" and present the options to your customer.


Step 3 — Place the Order

POST /orders/json?userId=usr_abc123 HTTP/1.1
cmr-x-api-key: your_partner_api_key
Content-Type: application/json

{
  "billingCycle": "MONTHLY",
  "domains": [
    { "domain": "alicesender.com", "years": 1 }
  ],
  "mailboxes": {
    "alicesender.com": [
      { "username": "alice", "firstName": "Alice", "lastName": "Johnson" },
      { "username": "alice.j", "firstName": "Alice", "lastName": "Johnson" },
      { "username": "hello", "firstName": "Alice", "lastName": "Johnson" }
    ]
  }
}

Response:

{
  "status": 200,
  "message": "Order created and queued for processing",
  "data": {
    "orderId": "ord_R8K2LQPZA9XM",
    "metadata": { "alicesender.com": "Success" }
  }
}

Store data.orderId — pass it as the orderId query param on GET /orders/status to poll progress, and it's how incoming webhooks for this order can be correlated.

Order Fields

FieldRequiredDescription
billingCycleYesMONTHLY (only supported value currently)
domainsNoArray of { domain, years } objects to register. Omit entirely for mailbox-only orders on an existing domain.
mailboxesYesObject keyed by domain name → array of mailbox objects (username, firstName, lastName, optional onWarmup). Each mailbox's firstName/lastName is set per mailbox, not once for the whole order.

There is no mailboxesPerDomain field and no top-level firstName/lastName — a request in that shape will fail validation ("mailboxes must be an object").

WARNING

Never resubmit an order while waiting for webhooks. Duplicates create duplicate domain registrations and charges with no automatic way to reverse them.


Step 4 — Handle the Webhooks

A successful order produces a sequence of events — not a single webhook. Listen for all of them.

domain.order.success

Domain is registered. Mailbox provisioning begins immediately after.

{
  "event": "domain.order.success",
  "eventId": "6SSHBXWR3N4JEKGRQSG3KW3D76N6",
  "data": {
    "userId": "usr_abc123",
    "orderId": "NQ682GAVFTMYC2H6C87PPKPG5WXV",
    "domain": "alicesender.com"
  }
}

mailbox.created

Fires once per mailbox when it's fully provisioned and ready. If you ordered 3 mailboxes, you receive 3 separate mailbox.created events.

{
  "event": "mailbox.created",
  "eventId": "7TTIBYXS4O5KFLHSRTG4LX4E87O7",
  "data": {
    "userId": "usr_abc123",
    "orderId": "NQ682GAVFTMYC2H6C87PPKPG5WXV",
    "mailboxId": "mbx_001",
    "email": "alice@alicesender.com"
  }
}

domain.order.failed

{
  "event": "domain.order.failed",
  "eventId": "8UUJCZYT5P6LGMITSTG5MY5F98P8",
  "data": {
    "userId": "usr_abc123",
    "orderId": "NQ682GAVFTMYC2H6C87PPKPG5WXV",
    "reason": "Workspace Validation"
  }
}

TIP

Respond with HTTP 200 immediately when you receive any webhook — before processing. If your handler throws before responding, CMR will retry the delivery.


Adding Mailboxes to an Existing Domain

Once you have an active domain, add more mailboxes without a new domain order:

POST /orders/create-mailbox-order/json?userId=usr_abc123 HTTP/1.1
cmr-x-api-key: your_partner_api_key
Content-Type: application/json

{
  "domainId": "dom_xyz456",
  "billingCycle": "MONTHLY",
  "mailboxes": {
    "acmecorp.com": [
      { "username": "bob", "firstName": "Bob", "lastName": "Smith" },
      { "username": "bob.s", "firstName": "Bob", "lastName": "Smith" }
    ]
  }
}

There is no count field — list every mailbox you want created explicitly under mailboxes, keyed by the domain's actual domain name (not domainId). Same pattern — mailbox.created fires per mailbox when each is ready.


Sandbox Testing

Test the full flow without real charges:

POST /sandbox/orders/json?userId=usr_abc123 HTTP/1.1
cmr-x-sandbox-api-key: your_sandbox_api_key
Content-Type: application/json

{
  "billingCycle": "MONTHLY",
  "domains": [
    { "domain": "testdomain.com", "years": 1 }
  ],
  "mailboxes": {
    "testdomain.com": [
      { "username": "test", "firstName": "Test", "lastName": "User" }
    ]
  }
}

Sandbox mirrors the production request shape exactly — see Place the Order above.

Control the outcome via the cmr-x-sandbox-scenario header:

Header valueBehavior
simulate:order-successdomain.order.success → mailbox.order.success → mailbox.created events fire
simulate:order-domain-faileddomain.order.failed fires
simulate:order-partial-failureSome domains succeed, some fail

See the full Sandbox API reference for every sandboxed endpoint and scenario key.


Next Steps

Signature verification, deduplication, retry handling, and the full event reference. Partner-level vs user-level auth in more detail. Go deeper on domain search, forwarding, and status handling.
Modified at 2026-09-05 07:55:39
Previous
Authentication
Next
Users
Built with