# 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: ```bash 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)** ```json { "success": true, "data": { ... }, "message": "Operation completed successfully" } ``` **Error (4xx)** ```json { "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 ``` ```json { \"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) - `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"`. ```json { "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): 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"`. ```json { "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): 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"`. ```json { "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): 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`. ```json { "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): 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`. ```json { "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): 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) - `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): 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) - `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, 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"`. ```json { "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): 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, 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"`. ```json { "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): 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`. ```json { "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): 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"`. ```json { "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): 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, 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`. ```json { "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): 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, required): Domain IDs to remove forwarding from. Example: `["dom_abc123", "dom_def456"]`. ```json { "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): 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, 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"`. ```json { "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): 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, required): Domain IDs to remove DMARC from. Example: `["dom_abc123", "dom_def456"]`. ```json { "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): 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, required): IDs of the domains to push the client ID to. Example: `["01DEF...", "01GHI..."]`. ```json { "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): 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: ""` 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, 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`. ```json { "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): 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, required): IDs of the domains whose DNS records should be cleared. Example: `["01DEF...", "01GHI..."]`. ```json { "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): 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, required): IDs of the domains to delete. Example: `["01DEF...", "01GHI..."]`. ```json { "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): 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) - `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) - `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"`. ```json { "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): 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): 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): 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) - `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, 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"`. ```json { "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): 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): 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): 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, required): Mailbox IDs to clear forwarding for. Example: `["mbx_abc123", "mbx_def456"]`. ```json { "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): 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): 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, 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, 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"`. ```json { "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): 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) - `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): 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, required): Array of 1–50 pre-warm domain IDs to purchase. Example: `["pw-domain-1", "pw-domain-2"]`. ```json { "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) - `domain_id` (string) Example: `"01DEF..."`. - `domain_name` (string) Example: `"warmeddomain.com"`. - `domain_price` (number) Example: `5.5`. - `mailbox_count` (integer) Example: `3`. - `mailboxes` (array): 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) - `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): 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, 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"`. ```json { "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): 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, 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"]`. ```json { "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): 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, required): Domain names to resolve (1–100). Example: `["example.com", "notmine.com"]`. ```json { "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): 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:** ```json { "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:** ```json { "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:** ```json { "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:** ```json { "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:** ```json { "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:** ```json { "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:** ```json { "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:** ```json { "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:** ```json { "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:** ```json { "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): 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`. ```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): 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) - `id` (string) - `workspace_id` (string) - `url` (string) - `description` (string) - `is_active` (boolean) - `subscribed_events` (array) - `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) Example: `["order.mailbox.active", "order.mailbox.failed"]`. - `format` (string enum(json)) ```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): 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): 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): 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): 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`).