Icemail API

Introduction

The Icemail API provides programmatic access to manage your email infrastructure — domains, mailboxes, DNS records, workspaces, and billing.


Getting Started

Step 1 — Obtain your API Key

Log into your [Icemail Dashboard](https://icemail.ai), navigate to Settings > API Keys, and click Generate New Key.

> Important: Keep your API key secret. Never expose it in frontend code or public repositories.

Step 2 — Make your first request

Verify your API key by listing your workspaces:

curl -X GET https://app.icemail.ai/api/v1/workspace \
  -H "x-api-key: YOUR_API_KEY"

A successful response will return 200 with your workspace data.


Authentication

All requests require your API key in the x-api-key header:

x-api-key: YOUR_API_KEY

Requests without a valid key will return 403 Forbidden.


Base URL

https://app.icemail.ai/api/v1

Pagination

All list endpoints support pagination:

| Parameter | Default | Max | Description |
|---|---|---|---|
| `page` | 1 | — | Page number |
| `limit` | 10 | 50 | Items per page |
| `search` | — | — | Filter results (varies by endpoint) |

Example: GET /domain?page=2&limit=5&search=example


Roles & Permissions

Icemail uses role-based access control (RBAC). Each workspace member is assigned one of the following roles:

| Role | Description |
|---|---|
| **OWNER** | Full access — manage billing, invite users, and modify all resources. |
| **ADMIN** | Same as Owner, except cannot delete the workspace. |
| **EDITOR** | Manage domains, DNS, mailboxes, and forwarding. Cannot modify billing or invite users. |
| **VIEWER** | Read-only access to all resources. |

Permission requirements are noted on each endpoint below.


Response Format

All endpoints return a consistent JSON structure:

Success (200 / 201)

{
  "success": true,
  "data": { ... },
  "message": "Operation completed successfully"
}

Error (4xx)

{
  "success": false,
  "message": "Description of what went wrong",
  "errors": [{ "field": "name", "message": "name is required" }]
}

Error Codes

| Code | Meaning | Common Cause |
|---|---|---|
| `400` | Bad Request | Missing required fields or invalid data |
| `403` | Forbidden | Invalid API key or insufficient permissions |
| `404` | Not Found | Resource ID does not exist |
| `409` | Conflict | Duplicate entry (e.g. user already invited) |

Rate Limiting

All v1 API endpoints are rate-limited using a dual-window system (burst + sustained) to prevent abuse while allowing normal usage patterns.

Default Limits

| Endpoint Pattern | Burst (per second) | Sustained (per minute) |
|---|---|---|
| `POST /v1/export` | 1 req/s | 1 req/day (per mailbox, per vendor — unlimited for `sequencer: other`) |
| `GET /v1/export/:id` | 5 req/s | 30 req/min |
| `GET /v1/mailbox/:id/auth` | 5 req/s | 30 req/min |
| `PUT /v1/mailbox/*` | 5 req/s | 20 req/min |
| `* /v1/domain/:id/dns-records` | 5 req/s | 20 req/min |
| `PUT,DELETE /v1/domain/forwarding,dmarc` | 1 req/s | 10 req/min |
| `POST /v1/order` | 1 req/5s | 12 req/min |
| `POST /v1/wallet/topup` | 1 req/10s | 20 req/min |
| `POST /v1/prewarm/buy` | 1 req/5s | 12 req/min |
| `* /v1/prewarm*` | 5 req/s | 30 req/min |
| `* /v1/domain*` | 5 req/s | 30 req/min |
| `* /v1/mailbox*` | 5 req/s | 30 req/min |
| All other endpoints | 5 req/s | 30 req/min |

Entity-Scoped Limits

POST /v1/export is rate-limited per mailbox_id, per destination vendor (sequencer), per day. Each mailbox in mailbox_ids consumes a separate rate limit point, keyed to the sequencer in the request — so a mailbox already exported today to instantly can still be exported today to smartlead. Exports with sequencer: "other" are exempt from this limit entirely.

Only an accepted export (201) counts. A request refused with 429, or one that fails, uses no quota. The window is a rolling 24 hours from the accepted export. If any mailbox in mailbox_ids is over its limit, the whole request is refused and nothing is exported. A repeated mailbox ID is counted once.

Response Headers

Every response includes rate limit headers based on the sustained (per-minute) window:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 25
X-RateLimit-Reset: 1700000060

Rate Limit Exceeded (429)

When rate limited, a Retry-After header is also included:

Retry-After: 60
{
  \"success\": false,
  \"message\": \"Too many requests. Please try again later.\",
  \"retry_after\": 60
}

For POST /v1/export, the body also includes blocked: the ID of every mailbox in mailbox_ids that is over its limit. Retry-After is the number of seconds until the first blocked mailbox can be exported again (up to 86400). Don't resend the same batch on a fixed timer: remove the blocked IDs, wait 1–2 seconds (resending a mailbox within 1 second hits the burst limit), and resend the rest.


Permission Matrix

| Endpoint | OWNER | ADMIN | EDITOR | VIEWER |
|---|---|---|---|---|
| GET /v1/workspace | Yes | Yes | Yes | Yes |
| POST /v1/workspace | Yes | Yes | No | No |
| PUT /v1/workspace | Yes | Yes | No | No |
| POST /v1/workspace/invite | Yes | Yes | No | No |
| GET /v1/wallet | Yes | Yes | Yes | Yes |
| PUT /v1/wallet/auto-topup | Yes | Yes | No | No |
| POST /v1/wallet/topup | Yes | Yes | No | No |
| GET /v1/domain | Yes | Yes | Yes | Yes |
| GET /v1/domain/available | Yes | Yes | Yes | Yes |
| GET /v1/domain/:id | Yes | Yes | Yes | Yes |
| GET /v1/domain/ns-records | Yes | Yes | Yes | Yes |
| GET /v1/domain/:id/dns-records | Yes | Yes | Yes | Yes |
| POST /v1/domain/:id/dns-records | Yes | Yes | Yes | No |
| PUT /v1/domain/:id/dns-records | Yes | Yes | Yes | No |
| PUT /v1/domain/:id/forwarding | Yes | Yes | Yes | No |
| PUT /v1/domain/:id/dmarc | Yes | Yes | Yes | No |
| PUT /v1/domain/forwarding | Yes | Yes | Yes | No |
| PUT /v1/domain/dmarc | Yes | Yes | Yes | No |
| POST /v1/domain/add-google-client-id | Yes | Yes | Yes | No |
| DELETE /v1/domain/forwarding | Yes | Yes | Yes | No |
| DELETE /v1/domain/dmarc | Yes | Yes | Yes | No |
| DELETE /v1/domain/mailboxes | Yes | Yes | Yes | No |
| DELETE /v1/domain/clear-dns | Yes | Yes | Yes | No |
| DELETE /v1/domain | Yes | Yes | Yes | No |
| GET /v1/mailbox | Yes | Yes | Yes | Yes |
| GET /v1/mailbox/:id | Yes | Yes | Yes | Yes |
| GET /v1/mailbox/domain/:id | Yes | Yes | Yes | Yes |
| GET /v1/mailbox/price | Yes | Yes | Yes | Yes |
| PUT /v1/mailbox/:id | Yes | Yes | Yes | No |
| PUT /v1/mailbox/forwarding | Yes | Yes | Yes | No |
| DELETE /v1/mailbox/forwarding | Yes | Yes | Yes | No |
| GET /v1/mailbox/:id/auth | Yes | Yes | Yes | Yes |
| GET /v1/mailbox/:id/app-password | Yes | Yes | Yes | Yes |
| POST /v1/order | Yes | Yes | Yes | No |
| GET /v1/prewarm | Yes | Yes | Yes | Yes |
| POST /v1/prewarm/buy | Yes | Yes | Yes | No |
| POST /v1/export | Yes | Yes | Yes | No |
| GET /v1/export/:id | Yes | Yes | Yes | Yes |
| POST /v1/export/republish/:id | Yes | Yes | Yes | No |
| POST /v1/lookup/mailboxes | Yes | Yes | Yes | Yes |
| POST /v1/lookup/domains | Yes | Yes | Yes | Yes |
| GET /v1/webhook | Yes | Yes | Yes | Yes |
| POST /v1/webhook | Yes | Yes | No | No |
| PUT /v1/webhook/:id | Yes | Yes | No | No |
| DELETE /v1/webhook/:id | Yes | Yes | No | No |

Support

Visit [icemail.ai](https://icemail.ai) or contact our support team for assistance.

Base URL: https://app.icemail.ai/api/v1

Workspace

Workspaces are the top-level container in Icemail. All domains, mailboxes, and billing are scoped to a workspace.

Use these endpoints to create and update workspaces, and to invite team members with role-based access.

GET /workspace

List Workspaces

Returns all workspaces accessible by the authenticated API key.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/workspace

Responses

• 200: List of workspaces.
• success (boolean) Example: true.
• data (array<object>)
• id (string (uuid)): Unique workspace identifier. Example: "ws_a1b2c3d4".
• name (string): Display name of the workspace. Example: "My Company".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

POST /workspace

Create Workspace

Creates a new workspace.

A new API key scoped to the created workspace is generated and returned as api_key. Use it in the x-api-key header for requests against that workspace.

Rate limit: 5 req/s burst, 30 req/min sustained

POST https://app.icemail.ai/api/v1/workspace

Request body (application/json, required)

• name (string, required): Workspace display name. Example: "My New Workspace".
{
  "name": "My New Workspace"
}

Responses

• 201: Workspace created.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

PUT /workspace

Update Workspace

Renames the current workspace.

Rate limit: 5 req/s burst, 30 req/min sustained

PUT https://app.icemail.ai/api/v1/workspace

Request body (application/json, required)

• name (string, required): New workspace name. Example: "Updated Workspace Name".
{
  "name": "Updated Workspace Name"
}

Responses

• 200: Workspace updated.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

POST /workspace/invite

Invite User to Workspace

Sends an email invitation to join the workspace with the specified role.

Assignable roles: ADMIN, EDITOR, VIEWER

Returns 409 if the user is already a workspace member.

Rate limit: 5 req/s burst, 30 req/min sustained

POST https://app.icemail.ai/api/v1/workspace/invite

Request body (application/json, required)

• email (string (email), required): Invitee's email address. Example: "teammate@company.com".
• role (string enum(ADMIN, EDITOR, VIEWER), required): Role to assign. Example: "EDITOR".
{
  "email": "teammate@company.com",
  "role": "EDITOR"
}

Responses

• 201: Invitation sent.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 409: Conflict — A duplicate entry already exists.
• success (boolean) Example: false.
• message (string) Example: "Already a member of this workspace".

Wallet

The wallet manages your workspace's credit balance and auto top-up configuration.

Credits are consumed when provisioning domains, mailboxes, and other billable resources.

GET /wallet

Get Wallet Balance

Returns the current wallet balance and auto top-up configuration.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/wallet

Responses

• 200: Wallet details.
• success (boolean) Example: true.
• data (object): Workspace billing wallet with balance and auto top-up settings.
• balance (number): Current balance in account currency. Example: 125.5.
• currency (string): ISO 4217 currency code. Example: "USD".
• auto_topup (object): When enabled, the wallet is recharged automatically when balance drops below the threshold.
• enabled (boolean): Whether auto top-up is active. Example: true.
• threshold (number): Balance threshold that triggers a top-up. Example: 10.
• topup_amount (number): Amount added per top-up. Example: 50.
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

PUT /wallet/auto-topup

Configure Auto Top-up

Enables or disables automatic wallet recharging.

When enabled, the wallet is topped up by topup_amount whenever the balance drops below threshold.

Rate limit: 5 req/s burst, 30 req/min sustained

PUT https://app.icemail.ai/api/v1/wallet/auto-topup

Request body (application/json, required)

• enabled (boolean, required): true to enable, false to disable.
• threshold (number): Balance threshold to trigger top-up. Required when enabled is true. Example: 10.
• topup_amount (number): Amount to add per top-up. Required when enabled is true. Example: 50.
{
  "enabled": true,
  "threshold": 10,
  "topup_amount": 50
}

Responses

• 200: Auto top-up settings updated.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

POST /wallet/topup

Top-up Wallet

Adds credits to the workspace wallet.

• If a saved payment method exists (auto-topup card on file), the charge is processed immediately and credits are added.
• Otherwise, a Stripe Checkout session is created and a checkout_url is returned. Credits are added automatically via webhook after payment.

> Note: After payment, check GET /wallet for the updated balance. No polling needed.

Amount: $1–$10,000 USD

Rate limit: 1 req/10s burst, 20 req/min sustained (workspace-scoped)

POST https://app.icemail.ai/api/v1/wallet/topup

Request body (application/json, required)

• amount (number, required): Amount in USD to add (5–10000). Example: 50.
{
  "amount": 50
}

Responses

• 200: Top-up completed immediately via saved card (auto-topup).
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 201: Checkout session created. User must complete payment at the returned URL. Credits are added automatically via webhook.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

Domain

Domains are the foundation of your email infrastructure. Each domain supports DNS records, URL forwarding, and DMARC policies.

Bulk endpoints are available for applying forwarding and DMARC settings across multiple domains simultaneously.

Domain Termination Flow

Winding a domain down is a three-stage process. Each stage has its own endpoint; pick the stage that matches what you want to do.

| Stage | Endpoint | What it ends | What survives |
|---|---|---|---|
| 1. Delete Mailboxes | `DELETE /domain/mailboxes` | Every mailbox on the domain | The domain row + its DNS zone (records may stay too) |
| 2. Clear DNS Records | `DELETE /domain/clear-dns` | All MX / SPF / DKIM / DMARC / forwarding records | The zone itself + the Domains row — ready to reuse |
| 3. Delete Domains | `DELETE /domain` | The Domains row + ClouDNS zone + leftover inactive mailbox history | Nothing — the domain is removed from your listing (permanent) |

Common flows:

• Wind down everything permanently → DELETE /domain/mailboxes (immediate) → wait for vendor cleanup → DELETE /domain.
• Reuse the domain for a fresh mailbox batch → DELETE /domain/mailboxes (immediate) → DELETE /domain/clear-dns. Domain stays in your listing, zone is empty and ready.
• Stop paying at the end of the current cycle → DELETE /domain/mailboxes with mode: "scheduled". Mailboxes keep working until their billing date, then auto-delete.

Each endpoint enforces preconditions and silently skips domains that don't qualify (rather than erroring the whole batch) — call the missing stage first and retry.

GET /domain/available

Check Domain Availability

Checks whether a domain is available for purchase and returns pricing information along with recommended alternatives.

Validation:

• domain is required and must be non-empty
• Must not be a subdomain (e.g., sub.example.com is rejected)
• Must not include protocol (http://, https://), www. prefix, or path
• Must include a valid TLD (e.g., example.com)
• Allowed TLDs: com, net, org, biz, live, info (configurable via TLD env variable)

Rate limit: 5 req/s burst, 30 req/min sustained (global domain rate limit)

GET https://app.icemail.ai/api/v1/domain/available

Parameters

• domain (query, string, required): Domain to check (e.g., example.com).
• page (query, integer, optional): Page number (starts at 1). Default: 1.
• prefix (query, string, optional): Comma-separated prefixes for suggestions (e.g., get,try).
• suffix (query, string, optional): Comma-separated suffixes for suggestions (e.g., hub,app).
• tld (query, string, optional): Comma-separated TLDs to filter (e.g., com,net,org). Allowed: com, net, org, biz, live, info.

Responses

• 200: Domain availability and recommendations.
• success (boolean) Example: true.
• data (object)
• current_domain (object)
• domain (string) Example: "example.com".
• available (boolean) Example: true.
• pricing (object)
• tld (string) Example: "com".
• price (number) Example: 12.99.
• currency (string) Example: "USD".
• duration (integer) Example: 1.
• duration_type (string) Example: "YEAR".
• recommended_domains (array<object>)
• domain (string)
• available (boolean)
• pricing (object)
• tld (string)
• price (number)
• currency (string)
• duration (integer)
• duration_type (string)
• message (string) Example: "Domain availability checked successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

GET /domain/{domainId}

Get Domain by ID

Returns details for a specific domain.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/domain/{domainId}

Parameters

• domainId (path, string (uuid), required): Domain ID.

Responses

• 200: Domain details.
• success (boolean) Example: true.
• data (object): A domain registered in your workspace.
• domain_id (string): Unique domain identifier. Example: "01DEF...".
• domain (string): Domain name. Example: "example.com".
• status (string): Current status (e.g. ACTIVE, PENDING). Example: "ACTIVE".
• created_at (string (date-time)): When the domain was created. Example: "2026-04-27T10:00:00.000Z".
• expires_at (string (date-time)): Domain registration expiry date. null for domains with no expiry set (e.g. some imported/connected domains). Example: "2027-04-27T10:00:00.000Z".
• import (boolean): Whether the domain was imported (vs. purchased through Icemail). Example: false.
• order_id (string): Identifier of the order that created this domain. Example: "01ABC...".
• mailbox_count (integer): Number of mailboxes on this domain. Example: 3.
• domain_forwarding (boolean): Whether domain forwarding is enabled. Example: false.
• domain_forwarding_url (string): Forwarding destination URL. Empty string when not configured. Example: "".
• dmarc_email (string): DMARC report recipient. Empty string when not configured. Example: "".
• dmarc (boolean): Whether a DMARC record is present. Example: true.
• forwarding (boolean): Whether forwarding is configured. Example: false.
• spf (boolean): Whether the SPF record is present. Example: true.
• dkim (boolean): Whether the DKIM record is present. Example: true.
• mx_records (boolean): Whether MX records are present. Example: true.
• active (boolean): Whether the domain is active. Example: true.
• workspace_type (string enum(GOOGLE, MICROSOFT)): Email provider associated with the domain. Example: "GOOGLE".
• cf_app_id (string): Cloudflare app identifier, or null if the domain is not Cloudflare-managed. Example: null.
• prewarmed (boolean): Whether the domain came from the pre-warm pool. Example: false.
• associate_with_google (boolean): Whether the domain is associated with Google Workspace. Example: true.
• associate_with_microsoft (boolean): Whether the domain is associated with Microsoft 365. Example: false.
• blacklisted (boolean): Whether the domain is blacklisted. Example: false.
• message (string) Example: "Domain fetched successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

GET /domain/ns-records

Fetch Nameservers

Returns the Icemail nameservers (NS records) that your domains should point to at your registrar.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/domain/ns-records

Responses

• 200: Nameserver records.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

GET /domain/{domainId}/dns-records

Get DNS Records

Returns all DNS records for a domain.

Rate limit: 5 req/s burst, 20 req/min sustained

GET https://app.icemail.ai/api/v1/domain/{domainId}/dns-records

Parameters

• domainId (path, string (uuid), required): Domain ID.

Responses

• 200: DNS record list.
• success (boolean) Example: true.
• data (array<object>)
• id (string): Record identifier. Required when updating. Example: "rec_001".
• type (string enum(A, AAAA, CNAME, MX, TXT, NS, SRV, PTR, HTTPS, SVCB, TLSA, CAA)): DNS record type.
• name (string): Record name. Use @ for root domain. Example: "@".
• content (string): Record value (IP, hostname, or text depending on type). Example: "1.2.3.4".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

POST /domain/{domainId}/dns-records

Create DNS Records

Creates one or more DNS records for a domain.

Supported types: A, AAAA, CNAME, MX, TXT, NS, SRV, PTR, HTTPS, SVCB, TLSA, CAA

Use @ as the name to target the root domain.

Rate limit: 5 req/s burst, 20 req/min sustained

POST https://app.icemail.ai/api/v1/domain/{domainId}/dns-records

Parameters

• domainId (path, string (uuid), required): Domain ID.

Request body (application/json, required)

• records (array<object>, required): One or more DNS records to create.
• type (string enum(A, AAAA, CNAME, MX, TXT, NS, SRV, PTR, HTTPS, SVCB, TLSA, CAA), required)
• name (string, required): Record name. @ for root, or a subdomain (e.g. www, mail). Example: "@".
• content (string, required): Record value. Example: "1.2.3.4".
{
  "records": [
    {
      "type": "A",
      "name": "@",
      "content": "1.2.3.4"
    },
    {
      "type": "MX",
      "name": "@",
      "content": "mail.example.com"
    },
    {
      "type": "TXT",
      "name": "@",
      "content": "v=spf1 include:example.com ~all"
    }
  ]
}

Responses

• 201: Records created.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

PUT /domain/{domainId}/dns-records

Update DNS Records

Updates existing DNS records. Each record in the array must include its id.

Use GET /domain/{domainId}/dns-records to retrieve record IDs.

Rate limit: 5 req/s burst, 20 req/min sustained

PUT https://app.icemail.ai/api/v1/domain/{domainId}/dns-records

Parameters

• domainId (path, string (uuid), required): Domain ID.

Request body (application/json, required)

• records (array<object>, required): Records to update. Each must include the existing id.
• id (string, required): Existing record ID. Example: "rec_001".
• type (string enum(A, AAAA, CNAME, MX, TXT, NS, SRV, PTR, HTTPS, SVCB, TLSA, CAA), required)
• name (string, required) Example: "@".
• content (string, required) Example: "5.6.7.8".
{
  "records": [
    {
      "id": "rec_001",
      "type": "A",
      "name": "@",
      "content": "5.6.7.8"
    }
  ]
}

Responses

• 200: Records updated.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

PUT /domain/{domainId}/forwarding

Update Domain Forwarding

Sets a forwarding URL for a domain. Visitors to this domain will be redirected to the specified URL.

Rate limit: 5 req/s burst, 30 req/min sustained

PUT https://app.icemail.ai/api/v1/domain/{domainId}/forwarding

Parameters

• domainId (path, string (uuid), required): Domain ID.

Request body (application/json, required)

• forwarding_url (string (uri), required): Destination URL (must include protocol). Example: "https://example.com".
• mask (boolean): Forwarding method for non-Cloudflare domains. true (default) uses domain masking; false uses basic 301 redirect. Ignored for Cloudflare-connected domains. Default: True.
{
  "forwarding_url": "https://example.com",
  "mask": true
}

Responses

• 200: Forwarding configured.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

PUT /domain/{domainId}/dmarc

Update DMARC Record

Configures DMARC for a domain by setting the email that receives aggregate reports.

DMARC (Domain-based Message Authentication, Reporting & Conformance) helps prevent email spoofing.

Rate limit: 5 req/s burst, 30 req/min sustained

PUT https://app.icemail.ai/api/v1/domain/{domainId}/dmarc

Parameters

• domainId (path, string (uuid), required): Domain ID.

Request body (application/json, required)

• dmarc_email (string (email), required): Email to receive DMARC reports. Example: "dmarc-reports@example.com".
{
  "dmarc_email": "dmarc-reports@example.com"
}

Responses

• 200: DMARC configured.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

PUT /domain/forwarding

Bulk Assign Forwarding

Applies the same forwarding URL to multiple domains in a single request.

Rate limit: 1 req/s burst, 10 req/min sustained

PUT https://app.icemail.ai/api/v1/domain/forwarding

Request body (application/json, required)

• domain_ids (array<string (uuid)>, required): Domain IDs to apply forwarding to. Example: ["dom_abc123", "dom_def456"].
• forwarding_url (string (uri), required): Destination URL for all listed domains. Example: "https://example.com".
• mask (boolean): Forwarding method for non-Cloudflare domains. true (default) uses domain masking; false uses basic 301 redirect. Ignored for Cloudflare-connected domains. Default: True.
{
  "domain_ids": [
    "dom_abc123",
    "dom_def456"
  ],
  "forwarding_url": "https://example.com",
  "mask": true
}

Responses

• 200: Forwarding applied.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

DELETE /domain/forwarding

Bulk Remove Forwarding

Removes forwarding configuration from multiple domains.

Rate limit: 1 req/s burst, 10 req/min sustained

DELETE https://app.icemail.ai/api/v1/domain/forwarding

Request body (application/json, required)

• domain_ids (array<string (uuid)>, required): Domain IDs to remove forwarding from. Example: ["dom_abc123", "dom_def456"].
{
  "domain_ids": [
    "dom_abc123",
    "dom_def456"
  ]
}

Responses

• 200: Forwarding removed.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

PUT /domain/dmarc

Bulk Assign DMARC

Applies the same DMARC reporting email to multiple domains.

Rate limit: 1 req/s burst, 10 req/min sustained

PUT https://app.icemail.ai/api/v1/domain/dmarc

Request body (application/json, required)

• domain_ids (array<string (uuid)>, required): Domain IDs to configure. Example: ["dom_abc123", "dom_def456"].
• dmarc_email (string (email), required): DMARC report recipient for all listed domains. Example: "dmarc-reports@example.com".
{
  "domain_ids": [
    "dom_abc123",
    "dom_def456"
  ],
  "dmarc_email": "dmarc-reports@example.com"
}

Responses

• 200: DMARC applied.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

DELETE /domain/dmarc

Bulk Remove DMARC

Removes DMARC configuration from multiple domains. DMARC reports will no longer be sent for these domains.

Rate limit: 1 req/s burst, 10 req/min sustained

DELETE https://app.icemail.ai/api/v1/domain/dmarc

Request body (application/json, required)

• domain_ids (array<string (uuid)>, required): Domain IDs to remove DMARC from. Example: ["dom_abc123", "dom_def456"].
{
  "domain_ids": [
    "dom_abc123",
    "dom_def456"
  ]
}

Responses

• 200: DMARC removed.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

POST /domain/add-google-client-id

Add Google OAuth Client ID

Pushes a Google OAuth client_id to the master inbox of each given domain (queues a CLIENTID export job per domain).

Each domain has a 15-minute cooldown — a domain processed within the last 15 minutes is returned under skipped instead of being re-queued.

The job runs asynchronously — subscribe to the order.client_id.completed / order.client_id.failed webhooks for the per-mailbox result.

Rate limit: 5 req/s burst, 30 req/min sustained

POST https://app.icemail.ai/api/v1/domain/add-google-client-id

Request body (application/json, required)

• client_id (string, required): Google OAuth client ID to push. Example: "1234567890-abcdef.apps.googleusercontent.com".
• domain_ids (array<string>, required): IDs of the domains to push the client ID to. Example: ["01DEF...", "01GHI..."].
{
  "client_id": "1234567890-abcdef.apps.googleusercontent.com",
  "domain_ids": [
    "01DEF...",
    "01GHI..."
  ]
}

Responses

• 200: Client ID push processed per domain.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

DELETE /domain/mailboxes

Delete Mailboxes by Domain

Stage 1 of the domain wind-down flow. Use when you want to wind down all mailboxes on one or more domains — either right now, or at the end of the current billing cycle to avoid forfeiting paid-for runway.

What it does: for each domain in domain_ids, deletes every mailbox on that domain. The Domains row, DNS zone, and DNS records are not touched — only the mailboxes go.

Modes:

• "immediate" (default) — Mailboxes are deleted permanently. There is no waiting period, recovery option, or undo action. Once a mailbox is deleted, all associated data is removed and cannot be restored. Only proceed if you are certain that you want to permanently delete the mailbox.
• "scheduled" — sets a scheduled_deletion_at on each mailbox equal to the earliest next_billing_date across the domain's active mailboxes. Mailboxes keep working normally until that date, then auto-delete via a trigger. Cancel by uncancelling the underlying subscription before the date arrives.

> Notes:

> - skipped: true on a per_domain entry means the domain had no active mailboxes — nothing to do.

> - error: "<message>" on a per_domain entry means that single domain failed (e.g. no billing data for scheduled mode); the rest of the batch still proceeds.

> - For scheduled mode the resolved date must be in the future. Domains whose next_billing_date is already past must use mode: "immediate".

Rate limit: 5 req/s burst, 30 req/min sustained

DELETE https://app.icemail.ai/api/v1/domain/mailboxes

Request body (application/json, required)

• domain_ids (array<string>, required): Non-empty array of domain IDs to wind down. Example: ["01DEF...", "01GHI..."].
• mode (string enum(immediate, scheduled)): immediate (default) soft-deletes now; scheduled deletes at the earliest next_billing_date (end-of-cycle). Default: immediate.
{
  "domain_ids": [
    "01DEF...",
    "01GHI..."
  ],
  "mode": "immediate"
}

Responses

• 200: Mailboxes deleted (or scheduled) per domain.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

DELETE /domain/clear-dns

Clear DNS Records

Stage 2 of the domain wind-down flow. Use when the domain has no active mailboxes anymore and you want to reuse it for a fresh mailbox batch. This is the right call after Delete Mailboxes when you don't want to give up the domain itself — just remove the stale MX / SPF / DKIM / DMARC / forwarding records tied to the old mailboxes.

What it does: queues a bulk action that, per domain, wipes every zone record except NS/SOA, resets the domain row's DNS flags (dkim, spf, dmarc, mx_records, forwarding, domain_forwarding) to false, and nulls the forwarding text fields. The DNS zone itself stays (so the domain is still ready to host records again) and the Domains row stays in your listing.

Why not just call Delete Domain? Delete Domain destroys the zone and removes the domain from your listing — if you intend to put new mailboxes on the same domain later, you'd have to re-import / re-purchase. Clear DNS keeps the zone alive so you can immediately allocate new mailboxes to it.

Per-domain preconditions enforced by the worker (silently skipped if not met):

• Domain must have zero active mailboxes — otherwise silently skipped (call Delete Mailboxes first).
• All-or-nothing on DNS deletion: if any record delete fails for a domain, that domain's flag reset is skipped — operator retries.

Async: responds 202 immediately with a correlation_id. Processing typically completes in 10–15 minutes.

Rate limit: 5 req/s burst, 30 req/min sustained

DELETE https://app.icemail.ai/api/v1/domain/clear-dns

Request body (application/json, required)

• domain_ids (array<string>, required): IDs of the domains whose DNS records should be cleared. Example: ["01DEF...", "01GHI..."].
{
  "domain_ids": [
    "01DEF...",
    "01GHI..."
  ]
}

Responses

• 202: Clear DNS action queued.
• success (boolean) Example: true.
• message (string) Example: "Clear DNS action queued \u2014 propagation typically completes in 10\u201315 minutes.".
• data (object)
• action (string) Example: "clear_dns_records".
• estimated_domains (integer) Example: 2.
• correlation_id (string) Example: "01HMR...".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

DELETE /domain

Delete Domains

Stage 3 of the domain wind-down flow — the terminal step. Use when you're done with the domain entirely and want it gone from your listing. After this the domain is no longer queryable through the public API and you can't reuse it without re-importing or re-purchasing.

What it does: queues a bulk action that, per domain, deletes the Domains row and any leftover inactive mailbox rows. For ClouDNS-hosted domains the zone is also deleted from ClouDNS. For Cloudflare-managed domains (connected via your own Cloudflare API key) the zone is left intact — only the platform's DB association is removed.

Per-domain preconditions enforced by the worker (silently skipped if not met):

• Purchased domains (import=false) are silently skipped. The registrar lifecycle for purchased domains is separate; this endpoint only handles connected domains you brought to the platform.
• Domains with active mailboxes are silently skipped. Call Delete Mailboxes by Domain first.

Async: responds 202 immediately with a correlation_id. Processing typically completes in 10–15 minutes.

> Warning: This is destructive. The Domains row and all linked inactive mailboxes are permanently deleted and are no longer queryable through the public API.

Rate limit: 5 req/s burst, 30 req/min sustained

DELETE https://app.icemail.ai/api/v1/domain

Request body (application/json, required)

• domain_ids (array<string>, required): IDs of the domains to delete. Example: ["01DEF...", "01GHI..."].
{
  "domain_ids": [
    "01DEF...",
    "01GHI..."
  ]
}

Responses

• 202: Delete Domain action queued.
• success (boolean) Example: true.
• message (string) Example: "Delete Domain action queued \u2014 propagation typically completes in 10\u201315 minutes.".
• data (object)
• action (string) Example: "delete_domain".
• estimated_domains (integer) Example: 2.
• correlation_id (string) Example: "01HMR...".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

GET /domain

List Domains

Returns all domains in the workspace with pagination and optional search.

The search parameter performs a case-insensitive partial match on the domain name.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/domain

Parameters

• page (query, integer, optional): Page number (starts at 1). Default: 1.
• limit (query, integer, optional): Items per page (max 50). Default: 10.
• search (query, string, optional): Filter by domain name (case-insensitive partial match).

Responses

• 200: Paginated domain list.
• success (boolean) Example: true.
• data (object)
• domains (array<object>)
• domain_id (string): Unique domain identifier. Example: "01DEF...".
• domain (string): Domain name. Example: "example.com".
• status (string): Current status (e.g. ACTIVE, PENDING). Example: "ACTIVE".
• created_at (string (date-time)): When the domain was created. Example: "2026-04-27T10:00:00.000Z".
• expires_at (string (date-time)): Domain registration expiry date. null for domains with no expiry set (e.g. some imported/connected domains). Example: "2027-04-27T10:00:00.000Z".
• import (boolean): Whether the domain was imported (vs. purchased through Icemail). Example: false.
• order_id (string): Identifier of the order that created this domain. Example: "01ABC...".
• mailbox_count (integer): Number of mailboxes on this domain. Example: 3.
• domain_forwarding (boolean): Whether domain forwarding is enabled. Example: false.
• domain_forwarding_url (string): Forwarding destination URL. Empty string when not configured. Example: "".
• dmarc_email (string): DMARC report recipient. Empty string when not configured. Example: "".
• dmarc (boolean): Whether a DMARC record is present. Example: true.
• forwarding (boolean): Whether forwarding is configured. Example: false.
• spf (boolean): Whether the SPF record is present. Example: true.
• dkim (boolean): Whether the DKIM record is present. Example: true.
• mx_records (boolean): Whether MX records are present. Example: true.
• active (boolean): Whether the domain is active. Example: true.
• workspace_type (string enum(GOOGLE, MICROSOFT)): Email provider associated with the domain. Example: "GOOGLE".
• cf_app_id (string): Cloudflare app identifier, or null if the domain is not Cloudflare-managed. Example: null.
• prewarmed (boolean): Whether the domain came from the pre-warm pool. Example: false.
• associate_with_google (boolean): Whether the domain is associated with Google Workspace. Example: true.
• associate_with_microsoft (boolean): Whether the domain is associated with Microsoft 365. Example: false.
• blacklisted (boolean): Whether the domain is blacklisted. Example: false.
• total_count (integer): Total domains matching the filter, across all pages. Example: 1.
• page (integer) Example: 1.
• limit (integer) Example: 10.
• message (string) Example: "Domains fetched successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

Mailbox

Mailboxes represent individual email accounts associated with your domains (e.g. john@yourdomain.com).

Each mailbox can be configured with forwarding rules and supports 2FA authenticator code retrieval.

GET /mailbox

List Mailboxes

Returns all mailboxes in the workspace with pagination, search, and provider filtering.

The search parameter matches against first_name, last_name, and username.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/mailbox

Parameters

• page (query, integer, optional): Page number (starts at 1). Default: 1.
• limit (query, integer, optional): Items per page (max 50). Default: 10.
• search (query, string, optional): Filter by name or username.
• provider (query, string enum(GOOGLE, MICROSOFT, CUSTOM), optional): Filter by provider.

Responses

• 200: Paginated mailbox list.
• success (boolean) Example: true.
• data (object)
• mailboxes (array<object>)
• id (string): Unique mailbox identifier. Example: "01GHI...".
• first_name (string): Owner's first name. Example: "John".
• last_name (string): Owner's last name. Example: "Doe".
• username (string): Full email address. Example: "john@example.com".
• recovery_email (string): Recovery email address. Example: "john.recovery@gmail.com".
• forward_email (string): Address that incoming mail is forwarded to. Example: "john.fwd@gmail.com".
• type (string enum(GOOGLE, MICROSOFT, CUSTOM)): GOOGLE — Google Workspace, MICROSOFT — Microsoft 365, CUSTOM — Custom SMTP/IMAP. Example: "GOOGLE".
• status (string): Current status (e.g. ACTIVE, UPDATING). Example: "ACTIVE".
• active (boolean): Whether the mailbox is active. Example: true.
• master_inbox (boolean): Whether this is the master (admin) inbox for its domain. Example: false.
• created_at (string (date-time)): When the mailbox was created. Example: "2026-04-27T10:00:00.000Z".
• modified_at (string (date-time)): When the mailbox was last modified. Example: "2026-04-27T10:00:00.000Z".
• password (string): Mailbox password, returned as decrypted plaintext. null for mailboxes without a stored password (e.g. OAuth-only). Treat the response as sensitive and avoid logging. Example: "Plaintext".
• domains (object): The domain this mailbox belongs to.
• domain_id (string): Domain identifier. Example: "01DEF...".
• domain (string): Domain name. Example: "example.com".
• next_billing_date (string (date-time)): Next billing date from the mailbox's purchase record. null when no purchase exists. Example: "2026-05-27T10:00:00.000Z".
• cost (string): Per-unit price as a decimal string (trailing zeros stripped, e.g. "4.9"). null when no purchase exists. Example: "4.99".
• billing_cycle (string enum(MONTHLY, YEARLY)): Billing cycle from the purchase record. null when no purchase exists. Example: "MONTHLY".
• total_count (integer): Total mailboxes matching the filter, across all pages. Example: 1.
• page (integer) Example: 1.
• limit (integer) Example: 10.
• message (string) Example: "Mailboxes fetched successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

GET /mailbox/price

Get Mailbox Prices

Returns direct (per-mailbox) pricing for GOOGLE and MICROSOFT, plus bundle-wise plan pricing for CUSTOM and AZURE — all in one call. All prices are in USD.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/mailbox/price

Responses

• 200: Resolved mailbox pricing.
• success (boolean) Example: true.
• data (object): Resolved mailbox pricing for the calling workspace — reflects any active pricing override, falling back to the tenant/plan default otherwise.
• direct (object): Per-mailbox price, at the only variant each provider is sold at (Google: admin panel, Microsoft: standard).
• GOOGLE (number): Per-mailbox monthly price for Google Workspace. Example: 5.0.
• MICROSOFT (number): Per-mailbox monthly price for Microsoft 365. Example: 4.0.
• bundles (object): Bundle-wise plan pricing, keyed by plan type.
• CUSTOM (object): CUSTOM plans, keyed by plan type (e.g. STARTER, GROWTH, PRO).
• AZURE (object): AZURE plans, keyed by plan type (e.g. BASIC).
• message (string) Example: "Mailbox prices fetched successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

GET /mailbox/{mailboxId}

Get Mailbox by ID

Returns details for a specific mailbox.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/mailbox/{mailboxId}

Parameters

• mailboxId (path, string (uuid), required): Mailbox ID.

Responses

• 200: Mailbox details. password is returned as decrypted plaintext (or null if not set) — treat the response as sensitive. Billing fields are null when no purchase record exists.
• success (boolean) Example: true.
• data (object): An email mailbox (e.g. john@yourdomain.com). Returned by GET /mailbox and GET /mailbox/{id}.
• id (string): Unique mailbox identifier. Example: "01GHI...".
• first_name (string): Owner's first name. Example: "John".
• last_name (string): Owner's last name. Example: "Doe".
• username (string): Full email address. Example: "john@example.com".
• recovery_email (string): Recovery email address. Example: "john.recovery@gmail.com".
• forward_email (string): Address that incoming mail is forwarded to. Example: "john.fwd@gmail.com".
• type (string enum(GOOGLE, MICROSOFT, CUSTOM)): GOOGLE — Google Workspace, MICROSOFT — Microsoft 365, CUSTOM — Custom SMTP/IMAP. Example: "GOOGLE".
• status (string): Current status (e.g. ACTIVE, UPDATING). Example: "ACTIVE".
• active (boolean): Whether the mailbox is active. Example: true.
• master_inbox (boolean): Whether this is the master (admin) inbox for its domain. Example: false.
• created_at (string (date-time)): When the mailbox was created. Example: "2026-04-27T10:00:00.000Z".
• modified_at (string (date-time)): When the mailbox was last modified. Example: "2026-04-27T10:00:00.000Z".
• password (string): Mailbox password, returned as decrypted plaintext. null for mailboxes without a stored password (e.g. OAuth-only). Treat the response as sensitive and avoid logging. Example: "Plaintext".
• domains (object): The domain this mailbox belongs to.
• domain_id (string): Domain identifier. Example: "01DEF...".
• domain (string): Domain name. Example: "example.com".
• next_billing_date (string (date-time)): Next billing date from the mailbox's purchase record. null when no purchase exists. Example: "2026-05-27T10:00:00.000Z".
• cost (string): Per-unit price as a decimal string (trailing zeros stripped, e.g. "4.9"). null when no purchase exists. Example: "4.99".
• billing_cycle (string enum(MONTHLY, YEARLY)): Billing cycle from the purchase record. null when no purchase exists. Example: "MONTHLY".
• message (string) Example: "Mailbox fetched successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

PUT /mailbox/{mailboxId}

Update Mailbox Details

Updates a mailbox's display name, username, or profile picture. At least one field must be provided.

Changing username will change the email address (e.g. john@example.com becomes jane@example.com).

Profile picture: pass a public profile_url (HTTPS, JPEG or PNG, max 10MB). The image is downloaded, validated, stored, and pushed to the mailbox provider; the previous profile picture is replaced. An invalid, oversized, non-image, or non-HTTPS URL returns 400.

Rate limit: 5 req/s burst, 20 req/min sustained

PUT https://app.icemail.ai/api/v1/mailbox/{mailboxId}

Parameters

• mailboxId (path, string (uuid), required): Mailbox ID.

Request body (application/json, required)

• first_name (string): New first name. Example: "John".
• last_name (string): New last name. Example: "Doe".
• username (string): New username (local part of email). Example: "johndoe".
• profile_url (string (uri)): Public HTTPS URL of the new profile picture (JPEG or PNG, max 5MB). Downloaded and replaces the existing picture. Example: "https://pic.com/avatar.jpg".
{
  "first_name": "John",
  "last_name": "Doe"
}

Responses

• 200: Mailbox update queued. The update is made, so status is returned as UPDATING. old_username appears on an entry only when the username changed; old_forward_email likewise appears only when the forwarding email changed.
• success (boolean) Example: true.
• data (object): Result of PUT /mailbox/{id} and PUT /mailbox/forwarding. Contains one entry per requested mailbox.
• updated_mailboxes (array<object>): Mailboxes that were successfully queued for update.
• id (string): Unique mailbox identifier. Example: "01GHI...".
• first_name (string): Owner's first name. Example: "John".
• last_name (string): Owner's last name. Example: "Doe".
• username (string): Full email address. Example: "johndoe@example.com".
• recovery_email (string): Recovery email address. Example: "john.recovery@gmail.com".
• forward_email (string): Address that incoming mail is forwarded to. Example: "john.fwd@gmail.com".
• type (string enum(GOOGLE, MICROSOFT, CUSTOM)): Email provider. Example: "GOOGLE".
• warmup_duration (integer): Warm-up period in days. Example: 14.
• created_at (string (date-time)): When the mailbox was created. Example: "2026-04-27T10:00:00.000Z".
• modified_at (string (date-time)): When the mailbox was last modified. Example: "2026-04-27T10:05:00.000Z".
• active (boolean): Whether the mailbox is active. Example: true.
• status (string): Current status. UPDATING while the change is queued to the vendor. Example: "UPDATING".
• domain_id (string): Identifier of the domain this mailbox belongs to. Example: "01DEF...".
• admin (boolean): Whether this mailbox is an admin. Example: false.
• cycle_intervel (integer): Billing cycle interval. Example: 0.
• old_username (string): Previous username. Present only when the username changed. Example: "john@example.com".
• old_forward_email (string): Previous forwarding email. Present only when the forwarding email changed. Example: "old.fwd@gmail.com".
• failed_updates (array<object>): Entries that failed validation.
• summary (object)
• total_requested (integer): Number of mailboxes in the request. Example: 1.
• successful (integer): Number of mailboxes successfully queued. Example: 1.
• failed (integer): Number of mailboxes that failed. Example: 0.
• message (string) Example: "Mailbox updated successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

GET /mailbox/domain/{domainId}

Get Mailboxes by Domain

Returns all mailboxes belonging to a specific domain.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/mailbox/domain/{domainId}

Parameters

• domainId (path, string (uuid), required): Domain ID.
• page (query, integer, optional): Page number (starts at 1). Default: 1.
• limit (query, integer, optional): Items per page (max 50). Default: 10.
• search (query, string, optional): Filter mailboxes within this domain.

Responses

• 200: Mailboxes for the domain. This endpoint returns a reduced mailbox shape that differs from GET /mailbox and GET /mailbox/{id}: it does not include password, the nested domains object, or the billing fields, and there is no total_count. It does add warmup_duration (warm-up period in days).
• success (boolean) Example: true.
• data (object)
• mailboxes (array<object>)
• id (string): Unique mailbox identifier. Example: "01GHI...".
• first_name (string): Owner's first name. Example: "John".
• last_name (string): Owner's last name. Example: "Doe".
• username (string): Full email address. Example: "john@example.com".
• recovery_email (string): Recovery email address. Example: "john.recovery@gmail.com".
• forward_email (string): Address that incoming mail is forwarded to. Example: "john.fwd@gmail.com".
• type (string enum(GOOGLE, MICROSOFT, CUSTOM)): Email provider. Example: "GOOGLE".
• warmup_duration (integer): Warm-up period in days. Example: 14.
• created_at (string (date-time)): When the mailbox was created. Example: "2026-04-27T10:00:00.000Z".
• modified_at (string (date-time)): When the mailbox was last modified. Example: "2026-04-27T10:00:00.000Z".
• active (boolean): Whether the mailbox is active. Example: true.
• status (string): Current status (e.g. ACTIVE). Example: "ACTIVE".
• domain_id (string): Identifier of the domain this mailbox belongs to. Example: "01DEF...".
• master_inbox (boolean): Whether this is the master (admin) inbox for its domain. Example: false.
• page (integer) Example: 1.
• limit (integer) Example: 10.
• message (string) Example: "Mailboxes fetched successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

PUT /mailbox/forwarding

Bulk Update Mailbox Forwarding

Sets the same forwarding email for multiple mailboxes. Incoming mail to these mailboxes will be forwarded to the specified address.

Rate limit: 5 req/s burst, 20 req/min sustained

PUT https://app.icemail.ai/api/v1/mailbox/forwarding

Request body (application/json, required)

• mailbox_ids (array<string (uuid)>, required): Mailbox IDs to configure. Example: ["mbx_abc123", "mbx_def456"].
• forward_email (string (email), required): Email address to forward to. Example: "team-inbox@company.com".
{
  "mailbox_ids": [
    "mbx_abc123",
    "mbx_def456"
  ],
  "forward_email": "team-inbox@company.com"
}

Responses

• 200: Forwarding update queued. Returns one entry per mailbox in mailbox_ids, with the same { updated_mailboxes, failed_updates, summary } shape as Update Mailbox Details.
• success (boolean) Example: true.
• data (object): Result of PUT /mailbox/{id} and PUT /mailbox/forwarding. Contains one entry per requested mailbox.
• updated_mailboxes (array<object>): Mailboxes that were successfully queued for update.
• id (string): Unique mailbox identifier. Example: "01GHI...".
• first_name (string): Owner's first name. Example: "John".
• last_name (string): Owner's last name. Example: "Doe".
• username (string): Full email address. Example: "johndoe@example.com".
• recovery_email (string): Recovery email address. Example: "john.recovery@gmail.com".
• forward_email (string): Address that incoming mail is forwarded to. Example: "john.fwd@gmail.com".
• type (string enum(GOOGLE, MICROSOFT, CUSTOM)): Email provider. Example: "GOOGLE".
• warmup_duration (integer): Warm-up period in days. Example: 14.
• created_at (string (date-time)): When the mailbox was created. Example: "2026-04-27T10:00:00.000Z".
• modified_at (string (date-time)): When the mailbox was last modified. Example: "2026-04-27T10:05:00.000Z".
• active (boolean): Whether the mailbox is active. Example: true.
• status (string): Current status. UPDATING while the change is queued to the vendor. Example: "UPDATING".
• domain_id (string): Identifier of the domain this mailbox belongs to. Example: "01DEF...".
• admin (boolean): Whether this mailbox is an admin. Example: false.
• cycle_intervel (integer): Billing cycle interval. Example: 0.
• old_username (string): Previous username. Present only when the username changed. Example: "john@example.com".
• old_forward_email (string): Previous forwarding email. Present only when the forwarding email changed. Example: "old.fwd@gmail.com".
• failed_updates (array<object>): Entries that failed validation.
• summary (object)
• total_requested (integer): Number of mailboxes in the request. Example: 1.
• successful (integer): Number of mailboxes successfully queued. Example: 1.
• failed (integer): Number of mailboxes that failed. Example: 0.
• message (string) Example: "Mailbox forwarding updated successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

DELETE /mailbox/forwarding

Bulk Delete Mailbox Forwarding

Removes email forwarding for the given mailboxes at the provider and clears forward_email. Processed asynchronously (takes a few minutes to propagate).

CUSTOM mailboxes are skipped — they have no provider forwarding rule. If every id is a CUSTOM mailbox (or none match the workspace), returns 400.

Rate limit: 5 req/s burst, 20 req/min sustained

DELETE https://app.icemail.ai/api/v1/mailbox/forwarding

Request body (application/json, required)

• mailbox_ids (array<string (uuid)>, required): Mailbox IDs to clear forwarding for. Example: ["mbx_abc123", "mbx_def456"].
{
  "mailbox_ids": [
    "mbx_abc123",
    "mbx_def456"
  ]
}

Responses

• 200: Forwarding removal queued for the given mailboxes.
• success (boolean) Example: true.
• message (string) Example: "Mailbox forwarding removal queued".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

GET /mailbox/{mailboxId}/auth

Get Authenticator Code

Returns the current 2FA TOTP code for a mailbox.

• If 2FA is configured: returns { token, remaining } with the 6-digit code and seconds until expiry.
• If 2FA is not configured: returns null.

TOTP codes typically refresh every 30 seconds.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/mailbox/{mailboxId}/auth

Parameters

• mailboxId (path, string (uuid), required): Mailbox ID.

Responses

• 200: Authenticator code or null.
• success (boolean) Example: true.
• data (object): Current 2FA TOTP code. Returns null if 2FA is not configured on the mailbox.
• token (string): Current 6-digit TOTP code. Example: "482913".
• remaining (integer): Seconds until this code expires. Example: 22.
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

GET /mailbox/{mailboxId}/app-password

Get Mailbox App Password

Returns the decrypted Google app password for a GOOGLE mailbox, or null when unset.

Non-Google mailboxes return 400; unknown ids return 404.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/mailbox/{mailboxId}/app-password

Parameters

• mailboxId (path, string (uuid), required): Mailbox ID (GOOGLE only).

Responses

• 200: App password or null.
• success (boolean) Example: true.
• data (object)
• app_password (string): Decrypted Google app password, or null if unset. Example: "abcd efgh ijkl mnop".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

Order

Orders allow you to purchase new domains or import existing ones, and provision mailboxes — all in a single request.

Credits are deducted for each domain and mailbox created. Importing existing domains skips the domain charge.

POST /order

Create Order

Purchases new domains and provisions mailboxes, or imports existing domains and creates mailboxes — all in a single request.

• import: false (default): Domains are purchased. Credits are charged for both domains and mailboxes. DNS is managed by Icemail.
• import: true: Domains are imported, so no domain purchase charge applies. Credits are charged for mailboxes only, and DNS is managed by Icemail.
• Cloudflare (optional): add a top-level cloudflare object (email + a scoped Cloudflare API api_key) to host the imported domains' DNS on your own Cloudflare zone instead of Icemail DNS; the same email reuses one stored connection. The api_key must be a Cloudflare API token with these permissions: Zone.Zone (Edit), Zone.DNS (Edit), and Zone Resources → All zones. Omit it for a normal import — don't send null / {} / a partial object (that returns 400).

> Note: Before importing a domain to Icemail, point your domain's nameservers at your registrar to pns71.cloudns.net, pns72.cloudns.com, pns73.cloudns.net, pns74.cloudns.uk.

>

> Skip this if you use your own Cloudflare account — the domain keeps its Cloudflare nameservers.

> Note: Avoid placing mailbox orders for the same domain through individual requests. Instead, submit all mailboxes for a domain in a single request to ensure proper processing and avoid workflow inconsistencies.

Bulk Providers (CUSTOM / AZURE)

CUSTOM (SMTP) and AZURE are bundle providers: they are sold as fixed-capacity plans rather than per-mailbox. You do not pick a plan — send the same domain_name + mailboxes shape as Google/Microsoft and the API auto-selects and purchases the cheapest plan(s) that fit your order, then allocates the mailboxes into them. Re-ordering for the same provider reuses any remaining capacity before buying more.

• CUSTOM — up to 15 mailboxes per domain. Plans cover STARTER (2 domains), GROWTH (4), PRO (6); the API picks the cheapest cover automatically.
• AZURE — each domain must have exactly 100 mailboxes (one BASIC plan = one domain). Provisioning is asynchronous: the order returns immediately with the mailboxes in PENDING status, and they become ACTIVE later (subscribe to the order.mailbox.active webhook or poll GET /api/v1/mailbox).

> The import: true flag works for bulk providers too (import an existing domain, pay for the bundle only). The AZURE 100-per-domain rule and the CUSTOM 15-per-domain limit still apply.

Constraints:

• data must contain 1–100 entries with no duplicate domain_name. Each request can include up to 100 domains (i.e., data.length ≤ 100).
• Each mailboxes[].username must end with @{domain_name}.
• first_name, last_name, and username are mandatory fields for each mailbox.
• password is optional. Omit it, or send null / "", and system generates a secure password for the mailbox. If you send one, it must:
• be 8–24 characters long
• start with a letter (A-Z / a-z)
• contain at least one uppercase letter, one lowercase letter, one number, and one symbol
• use only letters, numbers, and the symbols ! @ # $ % & ? (no spaces or other symbols)

An invalid password returns 400 with the rules in the error message. Example of a valid password: SecurePass1!.

• domain_forwarding, email_forwarding, and profile_url are optional.
• Per-provider mailbox counts: CUSTOM ≤ 15 mailboxes per domain; AZURE exactly 100 mailboxes per domain. (GOOGLE / MICROSOFT have no fixed per-domain cap.)

Rate limit: 1 req/5s burst, 12 req/min sustained (workspace-scoped)

POST https://app.icemail.ai/api/v1/order

Request body (application/json, required)

• import (boolean): true to import existing domains (no domain charge). false (default) to purchase new domains. Default: False. Example: false.
• cloudflare (object): Optional, import-only. Hosts the imported domains' DNS on your own Cloudflare zone instead of Icemail DNS. email + a scoped API api_key, reused per email. Omit for a Icemail DNS import (null / {} / partial → 400).
• email (string (email), required): Your Cloudflare account email. Example: "you@example.com".
• api_key (string, required): A Cloudflare API token. Required permissions: Zone.Zone (Edit), Zone.DNS (Edit), and Zone Resources → All zones. Stored as sent; not re-validated on later orders. Example: "cf_scoped_api_token_xxx".
• data (array<object>, required): Array of 1–100 domain entries. No duplicate domain_name allowed.
• domain_name (string, required): Domain to purchase or import. Example: "example.com".
• mailbox_type (string enum(GOOGLE, MICROSOFT, CUSTOM, AZURE), required): Email provider for the mailboxes. CUSTOM (SMTP) and AZURE are bundle providers — see Bulk Providers above. Example: "GOOGLE".
• domain_forwarding (string (uri)): Optional URL to forward the domain to. Example: "https://mysite.com".
• mailboxes (array<object>, required): Non-empty array of mailboxes to create for this domain. CUSTOM: ≤ 15 per domain. AZURE: exactly 100 per domain.
• first_name (string, required): First name. Example: "John".
• last_name (string, required): Last name. Example: "Doe".
• username (string, required): Full email address. Must end with @{domain_name}. Example: "john@example.com".
• password (string): Optional mailbox password. Omit it (or send null / empty string) to have Icemail auto-generate one. If provided: 8–24 characters, must start with a letter, and must contain at least one uppercase letter, one lowercase letter, one number, and one symbol from ! @ # $ % & ?. No spaces or other symbols are allowed. Invalid passwords return 400. Example: "SecurePass1!".
• email_forwarding (string (email)): Optional recovery/forwarding email. Example: "john.fwd@gmail.com".
• profile_url (string (uri)): Optional profile image URL. Example: "https://pic.com/avatar.jpg".
{
  "import": false,
  "data": [
    {
      "domain_name": "example.com",
      "mailbox_type": "GOOGLE",
      "domain_forwarding": "https://mysite.com",
      "mailboxes": [
        {
          "first_name": "John",
          "last_name": "Doe",
          "username": "john@example.com",
          "password": "SecurePass1!",
          "email_forwarding": "john.fwd@gmail.com",
          "profile_url": "https://pic.com/avatar.jpg"
        }
      ]
    },
    {
      "domain_name": "another.net",
      "mailbox_type": "MICROSOFT",
      "mailboxes": [
        {
          "first_name": "Jane",
          "last_name": "Smith",
          "username": "jane@another.net",
          "password": "SecurePass2!"
        }
      ]
    }
  ]
}

Responses

• 201: Order created. Returns one entry per domain in the same order as the request.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

Pre-Warm

Pre-warm domains to improve email deliverability before sending campaigns.

List and monitor domains that are in the pre-warming phase.

GET /prewarm

List Pre-Warm Domains

Returns all domains currently in the pre-warming phase with pagination and optional search.

The search parameter performs a case-insensitive partial match on the domain name.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/prewarm

Parameters

• page (query, integer, optional): Page number (starts at 1). Default: 1.
• limit (query, integer, optional): Items per page (max 100). Default: 10.
• search (query, string, optional): Filter by domain name (case-insensitive partial match).

Responses

• 200: Paginated list of pre-warm domains.
• success (boolean) Example: true.
• data (object)
• domains (array<object>)
• id (string): Pre-warm domain identifier. Example: "pw-domain-1".
• domain (string): Domain name. Example: "warmeddomain.com".
• per_domain_price (number): Price per domain. Example: 5.5.
• per_mailbox_price (number): Price per mailbox. Example: 2.5.
• mailbox_count (integer): Number of mailboxes on this domain. Example: 3.
• active (boolean): Whether the domain is actively pre-warming. Example: true.
• pre_warm_mailbox (array<object>): Mailboxes associated with this pre-warm domain.
• username (string): Full email address. Example: "john@warmeddomain.com".
• first_name (string): First name. Example: "John".
• last_name (string): Last name. Example: "Doe".
• type (string enum(GOOGLE, MICROSOFT)): Email provider. Example: "GOOGLE".
• admin (boolean): Whether this mailbox is an admin. Example: true.
• master_inbox (boolean): Whether this is the master inbox. Example: true.
• per_mailbox_price (number): Price for this mailbox. Example: 2.5.
• message (string) Example: "Pre-warm domains fetched successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

POST /prewarm/buy

Buy Pre-Warm Domains

Purchases one or more pre-warm domains. Credits are deducted for each domain and its associated mailboxes.

Returns details of successful and failed purchases.

> Note: On successful purchase, new domain IDs and mailbox IDs are generated and associated with your account. Use these IDs to manage the domains and mailboxes via the Domain and Mailbox endpoints.

Rate limit: 1 req/5s burst, 12 req/min sustained (workspace-scoped)

POST https://app.icemail.ai/api/v1/prewarm/buy

Request body (application/json, required)

• domain_ids (array<string>, required): Array of 1–50 pre-warm domain IDs to purchase. Example: ["pw-domain-1", "pw-domain-2"].
{
  "domain_ids": [
    "pw-domain-1",
    "pw-domain-2"
  ]
}

Responses

• 200: Purchase completed. Some domains may have failed.
• success (boolean) Example: true.
• data (object)
• order_id (string): Order identifier. Example: "01ABC...".
• successful_domains (array<object>)
• domain_id (string) Example: "01DEF...".
• domain_name (string) Example: "warmeddomain.com".
• domain_price (number) Example: 5.5.
• mailbox_count (integer) Example: 3.
• mailboxes (array<object>): Mailboxes created for this domain.
• mailbox_id (string) Example: "01GHI...".
• first_name (string) Example: "Admin".
• last_name (string) Example: "User".
• username (string) Example: "admin@warmeddomain.com".
• type (string enum(GOOGLE, MICROSOFT)) Example: "GOOGLE".
• master_inbox (boolean) Example: true.
• failed_domains (array<object>)
• domain_id (string) Example: "pw-unavailable".
• reason (string) Example: "Domain is reserved by another user".
• total_successful (integer) Example: 1.
• total_failed (integer) Example: 1.
• total_mailboxes_created (integer) Example: 3.
• total_cost (number) Example: 13.0.
• message (string) Example: "Pre-warm domains purchase completed".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 402: Insufficient credits.
• success (boolean) Example: false.
• message (string) Example: "Insufficient credits: available 5.00, required 13.00".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

Export

Export mailboxes directly to supported cold email sequencers (Instantly, Smartlead, Reachinbox, Emailbison, Plusvibe, Masterinbox, Salesforge, Sendkit, OutreachFox), or to an unlisted platform via other.

Each export is rate-limited per mailbox, per vendor, per day to prevent abuse — exports with sequencer: "other" are unlimited.

POST /export

Export Mailboxes to Sequencer

Exports one or more mailboxes to a supported cold email sequencer.

Each sequencer requires different credentials:

| Sequencer | Required Fields |
|---|---|
| `instantly` | `api_key`, `username`, `password`, `app_workspace_name` |
| `smartlead` | `username`, `password` |
| `reachinbox` | `api_key`, `username`, `password`, `app_workspace_name` |
| `emailbison` | `api_key` (super-admin token), `url`, `app_workspace_name`, `client_id` only for Google mailboxes |
| `plusvibe` | `username`, `password`, `app_workspace_name`, `client_id` only for Google mailboxes |
| `masterinbox` | `username`, `password`, `app_workspace_name` workspace ID of masterinbox |
| `salesforge` | `username`, `password`, `app_workspace_name` |
| `sendkit` | `api_key`, `username`, `password`, `app_workspace_name`, `client_id` only for Google mailboxes |
| `outreachfox` | `api_key`, `app_workspace_name` workspace ID for outreachfox |
| `other` | `name` (platform name, e.g. Emelia, Warmy, FirstQuadrant, Woodpecker, lemlist, Snov.io, Apollo.io, luella, SuperAGI, Reply). For platforms not listed above. `url`, `username`, `password`, `app_workspace_name`, `api_key` |

The export runs asynchronously — poll GET /export/{exportId} or subscribe to the order.export.completed webhook for the result.

Rate limit: 1 req/s burst, 1 accepted export per mailbox per vendor per rolling 24 hours (each mailbox_id + sequencer pair is counted separately; refused or failed requests don't count; exports with sequencer: "other" are exempt)

POST https://app.icemail.ai/api/v1/export

Request body (application/json, required)

• mailbox_ids (array<string (uuid)>, required): Mailbox IDs to export. Example: ["mbx_abc123", "mbx_def456"].
• sequencer (string enum(instantly, smartlead, reachinbox, emailbison, plusvibe, masterinbox, salesforge, sendkit, outreachfox, other), required): Target sequencer platform. Use other for a platform not listed here. Example: "instantly".
• name (string): Export name. Required for sequencer: "other" — name the target platform (e.g. Emelia, Warmy, FirstQuadrant, Woodpecker, lemlist, Snov.io, Apollo.io, luella, SuperAGI, Reply). Example: "API Export".
• username (string): Sequencer account username. Required for instantly, smartlead, reachinbox, plusvibe, masterinbox, salesforge, sendkit. Optional for other. Example: "user@example.com".
• password (string): Sequencer account password. Required for instantly, smartlead, reachinbox, plusvibe, masterinbox, salesforge, sendkit. Example: "secret".
• app_workspace_name (string): Workspace name within the sequencer (which is the workspace ID for masterinbox, and your IceMail workspace ID for outreachfox). Required for instantly, reachinbox, emailbison, plusvibe, masterinbox, salesforge, sendkit, and outreachfox. Example: "My Workspace".
• api_key (string): Sequencer API key. Required for instantly, reachinbox, emailbison, sendkit, and outreachfox. For emailbison, the token must be a super-admin token of the workspace you want to export into. Example: "ebk_xxx".
• url (string (uri)): Sequencer API base URL. Required for emailbison. For plusvibe, defaults to https://app.plusvibe.ai/v2/login. Example: "https://emailbison.api.com".
• client_id (string): Google OAuth client ID. Required when exporting Google mailboxes via emailbison, plusvibe, or sendkit. Not needed for Microsoft mailboxes. Example: "123456789.apps.googleusercontent.com".
{
  "mailbox_ids": [
    "mbx_abc123",
    "mbx_def456"
  ],
  "sequencer": "instantly",
  "api_key": "inst_xxx",
  "username": "user@example.com",
  "password": "secret",
  "app_workspace_name": "My Workspace"
}

Responses

• 201: Export job created. total is the number of mailboxes queued for export. The export runs asynchronously — poll GET /export/{exportId} or subscribe to the order.export.completed webhook for the result.
• success (boolean) Example: true.
• data (object)
• success (boolean) Example: true.
• export_id (string): Identifier of the created export. Example: "01JF8XC1D2E3F4G5H6J7K8L9M0".
• total (integer): Number of mailboxes queued for export. Example: 2.
• message (string) Example: "Mailbox export created successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 429: One or more mailboxes in mailbox_ids are over their limit: already exported to this sequencer in the last 24 hours, or sent again within 1 second. Nothing was exported and no quota was used. blocked lists the ID of every limited mailbox. retry_after is the wait in seconds for the first one. Remove the blocked IDs, wait 1–2 seconds, and resend the rest.

GET /export/{exportId}

Get Export Status

Returns the current status and progress of an export job.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/export/{exportId}

Parameters

• exportId (path, string, required): Export job ID.

Responses

• 200: Export job details.
• success (boolean) Example: true.
• data (object)
• id (string): Export job ID. Example: "exp_01ABC...".
• name (string): Export name. Example: "Instantly export".
• vendor (string): Target sequencer. Example: "instantly".
• status (string): Current status (pending, processing, completed, failed). Example: "completed".
• total (integer): Total mailboxes in this export. Example: 5.
• processed (integer): Mailboxes processed so far (successful + failed). Example: 5.
• format (string): Export format. Example: "json".
• created_at (string (date-time)): When the export was created.
• modified_at (string (date-time)): When the export was last updated.
• success (integer): Mailboxes exported successfully (processed - failed). Example: 4.
• failed (integer): Mailboxes whose export job failed. Republishing the export retries these. Example: 1.
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".

POST /export/republish/{exportId}

Republish Export (Retry Failed Export)

Retries or resumes a failed/stuck export. Automatically detects the stuck stage and resumes appropriately.

Cooldown: Once republished, the same export cannot be republished again for 2 hours (returns 429).

Rate limit: 5 req/s burst, 30 req/min sustained (general rate limit, workspace-scoped)

POST https://app.icemail.ai/api/v1/export/republish/{exportId}

Parameters

• exportId (path, string, required): Export job ID to republish.

Responses

• 200: Export republished successfully.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".
• 404: Not Found — The specified resource ID does not exist.
• success (boolean) Example: false.
• message (string) Example: "Resource not found".
• 429: Republish cooldown active (2 hours) or rate limit exceeded.

Lookup

Resolve human-readable identifiers to Icemail resource IDs in bulk.

Map usernames to mailbox IDs and domain names to domain IDs so you can reference resources by name without listing them first. Unknown names resolve to null.

POST /lookup/mailboxes

Resolve Mailbox IDs by Username

Resolves a batch of mailbox usernames (full email addresses, e.g. john@example.com) to their mailbox IDs within the workspace. Each requested username is returned as a key; unknown usernames resolve to null.

Validation: usernames must be a non-empty array of 1–100 non-empty strings.

Rate limit: 5 req/s burst, 30 req/min sustained

POST https://app.icemail.ai/api/v1/lookup/mailboxes

Request body (application/json, required)

• usernames (array<string>, required): Full mailbox email addresses to resolve (1–100). Matched exactly, so send them as stored (lowercase, no spaces). A bare name like john never matches. Example: ["john@example.com", "jane@example.com", "unknown@example.com"].
{
  "usernames": [
    "john@example.com",
    "jane@example.com",
    "unknown@example.com"
  ]
}

Responses

• 200: Mailbox IDs resolved.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

POST /lookup/domains

Resolve Domain IDs by Name

Resolves a batch of domain names to their domain IDs within the workspace. Each requested domain name is returned as a key; unknown domains resolve to null.

Validation: domains must be a non-empty array of 1–100 non-empty strings.

Rate limit: 5 req/s burst, 30 req/min sustained

POST https://app.icemail.ai/api/v1/lookup/domains

Request body (application/json, required)

• domains (array<string>, required): Domain names to resolve (1–100). Example: ["example.com", "notmine.com"].
{
  "domains": [
    "example.com",
    "notmine.com"
  ]
}

Responses

• 200: Domain IDs resolved.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

Webhooks

Overview

A webhook is an HTTP POST request that is automatically sent to your configured URL when a specific event occurs. Instead of polling the API for updates, webhooks push real-time data to your application the moment something happens.

Setting Up Webhooks

To configure a webhook, navigate to Settings > Notification > Add Webhook URL in the dashboard.

You will need to provide:

• URL — The HTTPS endpoint on your server that will receive webhook events
• Description (optional) — A label to identify the webhook

Retry Behavior

If your endpoint returns a non-2xx status code or times out (10 seconds), the delivery is retried up to 5 times with exponential backoff (30s, 60s, 120s, 240s, 480s). You can view delivery history and debug failures from Settings > Notification > Delivery Logs.

Controlling Which Events Fire

| Event |
|---|
| `order.mailbox.active` |
| `order.mailbox.failed` |
| `order.domain.active` |
| `order.domain.failed` |
| `order.export.completed` |
| `order.mailbox.deleted` |
| `order.mailbox.renewed` |
| `mailbox.renewal.reminder` |
| `domain.renewal.reminder` |
| `mailbox.app_password.updated` |
| `order.client_id.completed` |
| `order.client_id.failed` |

Managing Webhooks via the API

In addition to the dashboard, webhook endpoints can be fully managed via the API:

| Method | Endpoint | Required Role |
|---|---|---|
| `POST` | `/webhook` | OWNER, ADMIN |
| `GET` | `/webhook` | OWNER, ADMIN, EDITOR, VIEWER |
| `PUT` | `/webhook/{id}` | OWNER, ADMIN |
| `DELETE` | `/webhook/{id}` | OWNER, ADMIN |
• Omitting subscribed_events (or passing []) subscribes the endpoint to all events — this is the default.
• subscribed_events accepts raw event ids directly, e.g. ["order.mailbox.active", "order.mailbox.failed"].
• Maximum of 5 webhook endpoints per workspace.

Webhook Events

Every delivery uses the same envelope: event, timestamp, workspace_id, email (the workspace owner's email, resolved at dispatch time), and data (event-specific payload).

1. Mailbox Active (`order.mailbox.active`)

Triggered when all mailboxes in an order have been successfully created and are now active.

Trigger condition: Every mailbox in the order reaches ACTIVE status.

Sample Payload:

{
  "event": "order.mailbox.active",
  "timestamp": "2026-04-17T10:30:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "mailbox_count": 3,
    "mailboxes": [
      { "mailbox_id": "01JF8XA1B2C3D4E5F6G7H8J9K0", "username": "john@example.com" },
      { "mailbox_id": "01JF8XA2B3C4D5E6F7G8H9J0K1", "username": "jane@example.com" },
      { "mailbox_id": "01JF8XA3B4C5D6E7F8G9H0J1K2", "username": "mike@example.com" }
    ]
  }
}

2. Mailbox Failed (`order.mailbox.failed`)

Triggered when a mailbox creation fails during the provisioning process.

Trigger condition: A mailbox fails to be created by the vendor (Google, Microsoft, or Custom).

Sample Payload:

{
  "event": "order.mailbox.failed",
  "timestamp": "2026-04-17T10:35:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "failed_mailboxes": [
      {
        "mailbox_id": "01JF8XA4B5C6D7E8F9G0H1J2K3",
        "username": "alex@example.com",
        "error_message": "Mailbox creation failed: license limit reached",
        "error_code": "LICENSE_LIMIT"
      }
    ]
  }
}

3. Domain Active (`order.domain.active`)

Triggered when all domains in an order have been activated and DNS propagation is complete.

Trigger condition: Every domain in the order reaches ACTIVE status after nameserver verification.

Sample Payload:

{
  "event": "order.domain.active",
  "timestamp": "2026-04-17T11:00:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "domain_count": 2,
    "domains": [
      { "domain_id": "01JF8XB1C2D3E4F5G6H7J8K9L0", "domain": "example.com" },
      { "domain_id": "01JF8XB2C3D4E5F6G7H8J9K0L1", "domain": "example.io" }
    ]
  }
}

4. Domain Failed (`order.domain.failed`)

Triggered when one or more domain purchases or setups fail.

Trigger condition: A domain fails during purchase, DNS zone creation, or nameserver propagation.

Sample Payload:

{
  "event": "order.domain.failed",
  "timestamp": "2026-04-17T11:05:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "failed_domains": [
      {
        "domain_id": "01JF8XB3C4D5E6F7G8H9J0K1L2",
        "domain": "example.net",
        "error_message": "Domain purchase failed: payment declined"
      },
      {
        "domain_id": "01JF8XB4C5D6E7F8G9H0J1K2L3",
        "domain": "example.org",
        "error_message": "DNS zone creation failed: domain already exists"
      }
    ]
  }
}

5. Export Completed (`order.export.completed`)

Triggered when all mailbox export jobs for an order have finished processing. The payload splits mailboxes into successfully exported, failed, and pending (jobs that never reached a terminal state).

Trigger condition: All export jobs for the order have finished processing and no auto-retry is pending. Jobs that never resolved are still reported, in pending_mailboxes.

Sample Payload:

{
  "event": "order.export.completed",
  "timestamp": "2026-04-17T12:00:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "export_id": "01JF8XC1D2E3F4G5H6J7K8L9M0",
    "total": 4,
    "failed_count": 1,
    "completed_mailboxes": [
      { "mailbox_id": "01JF8XA1B2C3D4E5F6G7H8J9K0", "username": "john@example.com" },
      { "mailbox_id": "01JF8XA2B3C4D5E6F7G8H9J0K1", "username": "jane@example.com" }
    ],
    "failed_mailboxes": [
      { "mailbox_id": "01JF8XA3B4C5D6E7F8G9H0J1K2", "username": "mike@example.com", "error_message": "Export job failed: vendor rejected credentials" }
    ],
    "pending_mailboxes": [
      { "mailbox_id": "01JF8XA4B5C6D7E8F9G0H1J2K3", "username": "alex@example.com" }
    ]
  }
}

> Fields: total is the number of mailboxes in the export; failed_count is the number of failed jobs. completed_mailboxes + failed_mailboxes + pending_mailboxes together account for total. Failed entries include an error_message; pending_mailboxes contains jobs that never reached a terminal state.

6. Mailbox Deleted (`order.mailbox.deleted`)

Triggered when one or more mailboxes are deleted from a workspace.

Trigger condition: Mailboxes are deleted via the dashboard or API. Includes cascading deletions (e.g. deleting a Google admin master mailbox also deletes dependent mailboxes on the same domain).

Sample Payload:

{
  "event": "order.mailbox.deleted",
  "timestamp": "2026-04-17T14:00:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "deleted_count": 2,
    "mailboxes": [
      { "mailbox_id": "01JF8XA1B2C3D4E5F6G7H8J9K0", "username": "john@example.com" },
      { "mailbox_id": "01JF8XA2B3C4D5E6F7G8H9J0K1", "username": "jane@example.com" }
    ]
  }
}

7. Domain Renewal Reminder (`domain.renewal.reminder`)

Triggered 30 days before a domain's registration expires as a reminder to renew.

Trigger condition: A daily check identifies domains where the creation date plus the license duration is within 30 days. Only applies to domains that are not imported (import = false) and not Cloudflare-managed (cf_app_id is null).

Sample Payload:

{
  "event": "domain.renewal.reminder",
  "timestamp": "2026-04-17T04:00:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "domain_id": "01JF8XB1C2D3E4F5G6H7J8K9L0",
    "domain": "example.com",
    "created_at": "2025-05-17T00:00:00.000Z",
    "expires_at": "2026-05-17T00:00:00.000Z",
    "days_until_expiry": 30
  }
}

8. App Password Updated (`mailbox.app_password.updated`)

Triggered whenever a mailbox's app password is set or updated.

Trigger condition: Fires when an app password is written via the internal provisioning callback (app-password setup completing for a Google mailbox).

Sample Payload:

{
  "event": "mailbox.app_password.updated",
  "timestamp": "2026-04-17T15:00:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "mailbox_id": "01JF8XA1B2C3D4E5F6G7H8J9K0",
    "username": "john@example.com",
    "app_password": "abcd efgh ijkl mnop"
  }
}

> Security note: app_password is the plaintext app password. Only endpoints you trust should be subscribed to this event.

9. Google Client ID Completed (`order.client_id.completed`)

Triggered when a Google OAuth client ID pushed via POST /domain/add-google-client-id has been added to a domain's master inbox.

Trigger condition: One event per master inbox queued by the request, once its setup succeeds.

Sample Payload:

{
  "event": "order.client_id.completed",
  "timestamp": "2026-04-17T16:00:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "domain_id": "01JF8XB1C2D3E4F5G6H7J8K9L0",
    "domain": "example.com"
  }
}

10. Google Client ID Failed (`order.client_id.failed`)

Triggered when pushing a Google OAuth client ID via POST /domain/add-google-client-id fails for a domain's master inbox.

Trigger condition: One event per master inbox queued by the request, if its setup fails.

Sample Payload:

{
  "event": "order.client_id.failed",
  "timestamp": "2026-04-17T16:00:00.000Z",
  "workspace_id": "ws_abc123",
  "email": "owner@example.com",
  "data": {
    "domain_id": "01JF8XB1C2D3E4F5G6H7J8K9L0",
    "domain": "example.com",
    "error_message": "Client ID setup failed"
  }
}

POST /webhook

Create Webhook Endpoint

Creates a webhook endpoint for the workspace. Omitting subscribed_events (or passing []) subscribes the endpoint to all events by default.

Limit: Maximum of 5 webhook endpoints per workspace.

Rate limit: 5 req/s burst, 30 req/min sustained

POST https://app.icemail.ai/api/v1/webhook

Request body (application/json, required)

• url (string (uri), required): HTTPS endpoint that will receive webhook events. Example: "https://example.com/hooks/mail-events".
• description (string): Optional label to identify the webhook. Example: "Production order events".
• subscribed_events (array<string>): Event ids to subscribe to. Omit or pass [] to subscribe to all events. Example: ["order.mailbox.active", "order.mailbox.failed"].
• format (string enum(json)): Payload format. Only 'json' is supported currently. Default: json.
{
  "url": "https://example.com/hooks/mail-events",
  "description": "Production order events",
  "subscribed_events": [
    "order.mailbox.active",
    "order.mailbox.failed"
  ],
  "format": "json"
}

Responses

• 201: Webhook endpoint created.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

GET /webhook

List Webhook Endpoints

Returns all webhook endpoints configured for the workspace.

Rate limit: 5 req/s burst, 30 req/min sustained

GET https://app.icemail.ai/api/v1/webhook

Responses

• 200: List of webhook endpoints.
• success (boolean) Example: true.
• data (array<object>)
• id (string)
• workspace_id (string)
• url (string)
• description (string)
• is_active (boolean)
• subscribed_events (array<string>)
• format (string)
• created_at (string (date-time))
• updated_at (string (date-time))
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

PUT /webhook/{webhookId}

Update Webhook Endpoint

Updates a webhook endpoint. All fields are optional; only the fields provided are changed. Passing subscribed_events: [] switches the endpoint back to subscribing to all events.

Rate limit: 5 req/s burst, 30 req/min sustained

PUT https://app.icemail.ai/api/v1/webhook/{webhookId}

Parameters

• webhookId (path, string, required): Webhook endpoint ID.

Request body (application/json, required)

• url (string (uri)) Example: "https://example.com/hooks/mail-events-v2".
• is_active (boolean) Example: false.
• description (string) Example: "Production order events (v2)".
• subscribed_events (array<string>) Example: ["order.mailbox.active", "order.mailbox.failed"].
• format (string enum(json))
{
  "url": "https://example.com/hooks/mail-events-v2",
  "is_active": false,
  "description": "Production order events (v2)",
  "subscribed_events": [
    "order.mailbox.active",
    "order.mailbox.failed"
  ],
  "format": "json"
}

Responses

• 200: Webhook endpoint updated.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 400: Bad Request — Missing required fields or invalid data. See errors array for details.
• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

DELETE /webhook/{webhookId}

Delete Webhook Endpoint

Deletes a webhook endpoint. Its delivery history is deleted along with it.

Rate limit: 5 req/s burst, 30 req/min sustained

DELETE https://app.icemail.ai/api/v1/webhook/{webhookId}

Parameters

• webhookId (path, string, required): Webhook endpoint ID.

Responses

• 200: Webhook endpoint deleted.
• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".
• 403: Forbidden — Invalid API key or insufficient role permissions.
• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

Schemas

SuccessResponse

Standard success response.

• success (boolean): Always true for successful requests. Example: true.
• data (object): Response payload. Structure varies by endpoint.
• message (string): Human-readable status message. Example: "Operation completed successfully".

ValidationError

Returned when the request body or query parameters fail validation.

• success (boolean) Example: false.
• message (string) Example: "Validation failed".
• errors (array<object>): Field-level validation errors.
• field (string): The field that failed validation. Example: "name".
• message (string): Description of the validation failure. Example: "name is required".

PermissionError

Returned when the API key lacks the required role.

• success (boolean) Example: false.
• message (string) Example: "You don't have permission to perform this action".

NotFoundError

Returned when the specified resource does not exist.

• success (boolean) Example: false.
• message (string) Example: "Resource not found".

ConflictError

Returned when the operation would create a duplicate entry.

• success (boolean) Example: false.
• message (string) Example: "Already a member of this workspace".

Workspace

A workspace — the top-level organizational unit in Icemail.

• id (string (uuid)): Unique workspace identifier. Example: "ws_a1b2c3d4".
• name (string): Display name of the workspace. Example: "My Company".

Wallet

Workspace billing wallet with balance and auto top-up settings.

• balance (number): Current balance in account currency. Example: 125.5.
• currency (string): ISO 4217 currency code. Example: "USD".
• auto_topup (object): When enabled, the wallet is recharged automatically when balance drops below the threshold.
• enabled (boolean): Whether auto top-up is active. Example: true.
• threshold (number): Balance threshold that triggers a top-up. Example: 10.
• topup_amount (number): Amount added per top-up. Example: 50.

Domain

A domain registered in your workspace.

• domain_id (string): Unique domain identifier. Example: "01DEF...".
• domain (string): Domain name. Example: "example.com".
• status (string): Current status (e.g. ACTIVE, PENDING). Example: "ACTIVE".
• created_at (string (date-time)): When the domain was created. Example: "2026-04-27T10:00:00.000Z".
• expires_at (string (date-time)): Domain registration expiry date. null for domains with no expiry set (e.g. some imported/connected domains). Example: "2027-04-27T10:00:00.000Z".
• import (boolean): Whether the domain was imported (vs. purchased through Icemail). Example: false.
• order_id (string): Identifier of the order that created this domain. Example: "01ABC...".
• mailbox_count (integer): Number of mailboxes on this domain. Example: 3.
• domain_forwarding (boolean): Whether domain forwarding is enabled. Example: false.
• domain_forwarding_url (string): Forwarding destination URL. Empty string when not configured. Example: "".
• dmarc_email (string): DMARC report recipient. Empty string when not configured. Example: "".
• dmarc (boolean): Whether a DMARC record is present. Example: true.
• forwarding (boolean): Whether forwarding is configured. Example: false.
• spf (boolean): Whether the SPF record is present. Example: true.
• dkim (boolean): Whether the DKIM record is present. Example: true.
• mx_records (boolean): Whether MX records are present. Example: true.
• active (boolean): Whether the domain is active. Example: true.
• workspace_type (string enum(GOOGLE, MICROSOFT)): Email provider associated with the domain. Example: "GOOGLE".
• cf_app_id (string): Cloudflare app identifier, or null if the domain is not Cloudflare-managed. Example: null.
• prewarmed (boolean): Whether the domain came from the pre-warm pool. Example: false.
• associate_with_google (boolean): Whether the domain is associated with Google Workspace. Example: true.
• associate_with_microsoft (boolean): Whether the domain is associated with Microsoft 365. Example: false.
• blacklisted (boolean): Whether the domain is blacklisted. Example: false.

DnsRecord

A DNS record associated with a domain.

• id (string): Record identifier. Required when updating. Example: "rec_001".
• type (string enum(A, AAAA, CNAME, MX, TXT, NS, SRV, PTR, HTTPS, SVCB, TLSA, CAA)): DNS record type.
• name (string): Record name. Use @ for root domain. Example: "@".
• content (string): Record value (IP, hostname, or text depending on type). Example: "1.2.3.4".

Mailbox

An email mailbox (e.g. john@yourdomain.com). Returned by GET /mailbox and GET /mailbox/{id}.

• id (string): Unique mailbox identifier. Example: "01GHI...".
• first_name (string): Owner's first name. Example: "John".
• last_name (string): Owner's last name. Example: "Doe".
• username (string): Full email address. Example: "john@example.com".
• recovery_email (string): Recovery email address. Example: "john.recovery@gmail.com".
• forward_email (string): Address that incoming mail is forwarded to. Example: "john.fwd@gmail.com".
• type (string enum(GOOGLE, MICROSOFT, CUSTOM)): GOOGLE — Google Workspace, MICROSOFT — Microsoft 365, CUSTOM — Custom SMTP/IMAP. Example: "GOOGLE".
• status (string): Current status (e.g. ACTIVE, UPDATING). Example: "ACTIVE".
• active (boolean): Whether the mailbox is active. Example: true.
• master_inbox (boolean): Whether this is the master (admin) inbox for its domain. Example: false.
• created_at (string (date-time)): When the mailbox was created. Example: "2026-04-27T10:00:00.000Z".
• modified_at (string (date-time)): When the mailbox was last modified. Example: "2026-04-27T10:00:00.000Z".
• password (string): Mailbox password, returned as decrypted plaintext. null for mailboxes without a stored password (e.g. OAuth-only). Treat the response as sensitive and avoid logging. Example: "Plaintext".
• domains (object): The domain this mailbox belongs to.
• domain_id (string): Domain identifier. Example: "01DEF...".
• domain (string): Domain name. Example: "example.com".
• next_billing_date (string (date-time)): Next billing date from the mailbox's purchase record. null when no purchase exists. Example: "2026-05-27T10:00:00.000Z".
• cost (string): Per-unit price as a decimal string (trailing zeros stripped, e.g. "4.9"). null when no purchase exists. Example: "4.99".
• billing_cycle (string enum(MONTHLY, YEARLY)): Billing cycle from the purchase record. null when no purchase exists. Example: "MONTHLY".

DomainMailbox

Reduced mailbox shape returned by GET /mailbox/domain/{domainId}. Does not include password, the nested domains object, or billing fields; adds warmup_duration.

• id (string): Unique mailbox identifier. Example: "01GHI...".
• first_name (string): Owner's first name. Example: "John".
• last_name (string): Owner's last name. Example: "Doe".
• username (string): Full email address. Example: "john@example.com".
• recovery_email (string): Recovery email address. Example: "john.recovery@gmail.com".
• forward_email (string): Address that incoming mail is forwarded to. Example: "john.fwd@gmail.com".
• type (string enum(GOOGLE, MICROSOFT, CUSTOM)): Email provider. Example: "GOOGLE".
• warmup_duration (integer): Warm-up period in days. Example: 14.
• created_at (string (date-time)): When the mailbox was created. Example: "2026-04-27T10:00:00.000Z".
• modified_at (string (date-time)): When the mailbox was last modified. Example: "2026-04-27T10:00:00.000Z".
• active (boolean): Whether the mailbox is active. Example: true.
• status (string): Current status (e.g. ACTIVE). Example: "ACTIVE".
• domain_id (string): Identifier of the domain this mailbox belongs to. Example: "01DEF...".
• master_inbox (boolean): Whether this is the master (admin) inbox for its domain. Example: false.

UpdatedMailbox

A mailbox entry returned by the update endpoints. The update is queued to the vendor, so status is UPDATING.

• id (string): Unique mailbox identifier. Example: "01GHI...".
• first_name (string): Owner's first name. Example: "John".
• last_name (string): Owner's last name. Example: "Doe".
• username (string): Full email address. Example: "johndoe@example.com".
• recovery_email (string): Recovery email address. Example: "john.recovery@gmail.com".
• forward_email (string): Address that incoming mail is forwarded to. Example: "john.fwd@gmail.com".
• type (string enum(GOOGLE, MICROSOFT, CUSTOM)): Email provider. Example: "GOOGLE".
• warmup_duration (integer): Warm-up period in days. Example: 14.
• created_at (string (date-time)): When the mailbox was created. Example: "2026-04-27T10:00:00.000Z".
• modified_at (string (date-time)): When the mailbox was last modified. Example: "2026-04-27T10:05:00.000Z".
• active (boolean): Whether the mailbox is active. Example: true.
• status (string): Current status. UPDATING while the change is queued to the vendor. Example: "UPDATING".
• domain_id (string): Identifier of the domain this mailbox belongs to. Example: "01DEF...".
• admin (boolean): Whether this mailbox is an admin. Example: false.
• cycle_intervel (integer): Billing cycle interval. Example: 0.
• old_username (string): Previous username. Present only when the username changed. Example: "john@example.com".
• old_forward_email (string): Previous forwarding email. Present only when the forwarding email changed. Example: "old.fwd@gmail.com".

MailboxUpdateResult

Result of PUT /mailbox/{id} and PUT /mailbox/forwarding. Contains one entry per requested mailbox.

• updated_mailboxes (array<object>): Mailboxes that were successfully queued for update.
• id (string): Unique mailbox identifier. Example: "01GHI...".
• first_name (string): Owner's first name. Example: "John".
• last_name (string): Owner's last name. Example: "Doe".
• username (string): Full email address. Example: "johndoe@example.com".
• recovery_email (string): Recovery email address. Example: "john.recovery@gmail.com".
• forward_email (string): Address that incoming mail is forwarded to. Example: "john.fwd@gmail.com".
• type (string enum(GOOGLE, MICROSOFT, CUSTOM)): Email provider. Example: "GOOGLE".
• warmup_duration (integer): Warm-up period in days. Example: 14.
• created_at (string (date-time)): When the mailbox was created. Example: "2026-04-27T10:00:00.000Z".
• modified_at (string (date-time)): When the mailbox was last modified. Example: "2026-04-27T10:05:00.000Z".
• active (boolean): Whether the mailbox is active. Example: true.
• status (string): Current status. UPDATING while the change is queued to the vendor. Example: "UPDATING".
• domain_id (string): Identifier of the domain this mailbox belongs to. Example: "01DEF...".
• admin (boolean): Whether this mailbox is an admin. Example: false.
• cycle_intervel (integer): Billing cycle interval. Example: 0.
• old_username (string): Previous username. Present only when the username changed. Example: "john@example.com".
• old_forward_email (string): Previous forwarding email. Present only when the forwarding email changed. Example: "old.fwd@gmail.com".
• failed_updates (array<object>): Entries that failed validation.
• summary (object)
• total_requested (integer): Number of mailboxes in the request. Example: 1.
• successful (integer): Number of mailboxes successfully queued. Example: 1.
• failed (integer): Number of mailboxes that failed. Example: 0.

AuthCode

Current 2FA TOTP code. Returns null if 2FA is not configured on the mailbox.

• token (string): Current 6-digit TOTP code. Example: "482913".
• remaining (integer): Seconds until this code expires. Example: 22.

BundlePlan

A bundle-priced mailbox plan (CUSTOM, AZURE). price is the flat cost for the whole pack; individual mailbox prices within a pack are derived from price / mailbox_limit.

• mailbox_limit (integer): Number of mailboxes included in this plan. Example: 30.
• domain_limit (integer): Number of domains this plan can span. Example: 2.
• mailbox_per_domain (integer): Max mailboxes allowed per domain under this plan. Example: 15.
• price (number): Flat price for one pack of this plan. Example: 49.

MailboxPricing

Resolved mailbox pricing for the calling workspace — reflects any active pricing override, falling back to the tenant/plan default otherwise.

• direct (object): Per-mailbox price, at the only variant each provider is sold at (Google: admin panel, Microsoft: standard).
• GOOGLE (number): Per-mailbox monthly price for Google Workspace. Example: 5.0.
• MICROSOFT (number): Per-mailbox monthly price for Microsoft 365. Example: 4.0.
• bundles (object): Bundle-wise plan pricing, keyed by plan type.
• CUSTOM (object): CUSTOM plans, keyed by plan type (e.g. STARTER, GROWTH, PRO).
• AZURE (object): AZURE plans, keyed by plan type (e.g. BASIC).