{
  "openapi": "3.1.0",
  "info": {
    "title": "Coldmail API",
    "version": "v1",
    "description": "The Coldmail API provides programmatic access to create and manage high-deliverability cold email infrastructure: domain search and onboarding, mailbox provisioning, email sending with tracking, bounce analytics, warm-up configuration, and webhook notifications.\n\n## Quick Start\n\n### 1. Get API credentials\n\n**⚠️ Important**: API access and integrations are only available for **Scale plan** users.\n\nYour API credentials are automatically generated and displayed in your dashboard. Go to **Dashboard → [Integrations](https://my.coldmail.app/integrations)** to copy your **Client ID** and **API Key**. API keys are permanent until revoked.\n\n### 2. Make API calls\n\nAll requests are authenticated with a single header:\n\n```bash\ncurl https://my.coldmail.app/api/v1/domains \\\n  -H \"Authorization: ApiKey YOUR_CLIENT_ID:YOUR_API_KEY\"\n```\n\nWrite operations (POST, PATCH) additionally require an `Idempotency-Key` header containing a UUID:\n\n```bash\ncurl -X POST https://my.coldmail.app/api/v1/domains/connect \\\n  -H \"Authorization: ApiKey YOUR_CLIENT_ID:YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -d '{\"domain\": \"example.com\"}'\n```\n\n## Rate Limiting\n\n- **Limit**: 60 requests per minute per API client\n- **Headers**: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` are included in responses\n- **Reset**: every minute. Exceeding the limit returns `429 Too Many Requests` with a `retry_after` field.\n\n## Idempotency\n\nAll write operations require an `Idempotency-Key` header:\n\n- Must be a valid UUID\n- Prevents duplicate operations\n- Required for POST and PATCH operations\n\n## Webhooks\n\nWebhook endpoints are managed from the dashboard (not via the API). See the **Webhooks** section below for event payloads.\n\nWebhook deliveries are signed with HMAC-SHA256:\n\n- Header: `X-Coldmail-Signature: v1=<hex>`\n- Secret: the secret you provided during registration\n- Verification: compute HMAC-SHA256 of the raw request body with your secret and compare against the signature\n\n## Error Handling\n\nAll errors return consistent JSON responses:\n\n```json\n{\n  \"error\": \"Detailed error message\"\n}\n```\n\n**Common HTTP status codes:**\n\n- `400` — Bad Request (validation errors)\n- `401` — Unauthorized (invalid or missing credentials)\n- `402` — Payment Required (insufficient wallet balance or seat limit reached)\n- `404` — Not Found\n- `409` — Conflict (resource already exists or cannot be modified)\n- `429` — Too Many Requests (rate limit exceeded)\n- `500` — Internal Server Error\n\n## Best Practices\n\n1. **Always use idempotency keys** for write operations\n2. **Handle rate limits** by checking response headers\n3. **Verify webhook signatures** for security\n4. **Use batch operations** for multiple mailboxes\n5. **Monitor warm-up settings and mailbox health** to optimize sending volumes",
    "contact": {
      "name": "Coldmail Support",
      "url": "https://my.coldmail.app/integrations"
    }
  },
  "servers": [
    {
      "url": "https://my.coldmail.app/api",
      "description": "Production"
    }
  ],
  "security": [{ "apiKeyAuth": [] }],
  "tags": [
    {
      "name": "Domains",
      "description": "Search, purchase, or connect your own domains. Two ways to add a domain:\n\n1. **Purchase through Coldmail** — `GET /v1/domains/search` → `GET /v1/domains/availability` → `POST /v1/domains` (paid from your wallet, DNS fully managed).\n2. **Bring your own domain** — `POST /v1/domains/connect` to onboard, update your registrar nameservers, then `POST /v1/domains/{domain_id}/verify` to activate."
    },
    {
      "name": "Mailboxes",
      "description": "Provision and manage mailboxes on your active domains. Mailboxes are created in batches and billed monthly or annually."
    },
    {
      "name": "Sending",
      "description": "Send emails through your mailboxes. `POST /v1/send` (recommended) auto-selects an available mailbox with round-robin load balancing and automatic retry when a mailbox is rate-limited; `POST /v1/mailboxes/{mailbox_id}/send` targets a specific mailbox. HTML emails automatically get a tracking pixel — use the returned `trackingPixelId` and `emailLogId` to query analytics."
    },
    {
      "name": "Analytics & Bounces",
      "description": "Send/open/click statistics and unified bounce tracking.\n\nBounces are collected from multiple sources: SMTP rejections (`smtp_hard_bounce`/`smtp_soft_bounce`), provider bounce events (`provider_bounce`), DSN/mailer-daemon replies (`dsn_hard_bounce`/`dsn_soft_bounce`), and ColdBox classification (`inbox_ai_bounce`, `manual_bounce`, `unknown_bounce`).\n\nTwo scopes: `platform_sent` bounces are tied to a Coldmail send and count toward `total_bounced`/`bounce_rate`; `external_or_unknown` bounces were visible in the mailbox but not tied to a Coldmail send and count toward `external_bounces`/`mailbox_bounce_events`."
    },
    {
      "name": "Warmup & Health",
      "description": "Configure warm-up sending and monitor mailbox health and deliverability."
    }
  ],
  "paths": {
    "/v1/domains/search": {
      "get": {
        "tags": ["Domains"],
        "operationId": "searchDomains",
        "summary": "Search domain suggestions",
        "description": "Returns domain name suggestions for a brand keyword. Use `GET /v1/domains/availability` afterwards to confirm exact availability before purchasing.",
        "parameters": [
          {
            "name": "keyword",
            "in": "query",
            "required": true,
            "description": "Brand keyword to generate suggestions for, e.g. `mybrand`. Do **not** include a TLD.",
            "schema": { "type": "string", "example": "coldmail" }
          },
          {
            "name": "tlds",
            "in": "query",
            "required": false,
            "description": "Comma-separated TLD filter, e.g. `com,net,co`. Defaults to a curated list of supported TLDs.",
            "schema": { "type": "string", "example": "com,net" }
          }
        ],
        "responses": {
          "200": {
            "description": "Suggestions keyed by domain name.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keyword": { "type": "string", "example": "coldmail" },
                    "suggestions": {
                      "description": "Suggested domain names with availability. Always confirm with `GET /v1/domains/availability` before purchasing.",
                      "example": [
                        { "domain": "coldmail.com", "available": true },
                        { "domain": "coldmail.net", "available": true },
                        { "domain": "coldmail.co", "available": false }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/domains/availability": {
      "get": {
        "tags": ["Domains"],
        "operationId": "checkDomainAvailability",
        "summary": "Check domain availability",
        "description": "Checks exact availability of one or more full domain names. Repeat the `domain` parameter to check multiple domains (max 10 per request).",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": true,
            "description": "Full domain name, e.g. `example.com`. Repeatable: `?domain=a.com&domain=b.com` (max 10).",
            "explode": true,
            "schema": {
              "type": "array",
              "maxItems": 10,
              "items": { "type": "string", "example": "example.com" }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Availability results per domain.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "domain": { "type": "string", "example": "example.com" },
                          "available": { "type": "boolean", "example": true },
                          "status": {
                            "type": "string",
                            "description": "Raw registry status, e.g. `available`, `regthroughothers`, `regthroughus`.",
                            "example": "available"
                          },
                          "price": {
                            "type": ["number", "null"],
                            "description": "Purchase price in USD when available, otherwise null.",
                            "example": 14.0
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/domains": {
      "get": {
        "tags": ["Domains"],
        "operationId": "listDomains",
        "summary": "List domains",
        "responses": {
          "200": {
            "description": "All domains owned by your organization, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Domain" }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "tags": ["Domains"],
        "operationId": "purchaseDomain",
        "summary": "Purchase domain",
        "description": "Purchases a new domain using your wallet balance and sets up an annual renewal subscription. Verify availability first via `GET /v1/domains/availability` — domains passed to this endpoint are expected to have been checked beforehand.",
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["domain"],
                "properties": {
                  "domain": { "type": "string", "example": "example.com" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Domain purchased. DNS configuration follows automatically.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "integer", "example": 123 },
                    "domain": { "type": "string", "example": "example.com" },
                    "status": { "type": "string", "example": "pending_dns" },
                    "price": { "type": "number", "example": 14.0 },
                    "created_at": { "type": "string", "format": "date-time" },
                    "updated_at": { "type": "string", "format": "date-time" },
                    "message": {
                      "type": "string",
                      "example": "Domain purchased successfully. DNS configuration required."
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": {
            "description": "Insufficient wallet balance.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "string", "example": "Insufficient wallet balance" },
                    "required": { "type": "number", "example": 14.0 },
                    "current_balance": { "type": "number", "example": 5.5 }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Domain already exists.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" },
                "example": { "error": "Domain already exists" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/domains/connect": {
      "post": {
        "tags": ["Domains"],
        "operationId": "connectDomain",
        "summary": "Connect your own domain",
        "description": "Onboards a domain you already own. Coldmail creates a managed DNS zone and returns the nameservers to set at your registrar.\n\n**Flow:**\n1. `POST /v1/domains/connect` — returns nameservers\n2. Update nameservers at your registrar (GoDaddy, Namecheap, etc.)\n3. `POST /v1/domains/{domain_id}/verify` — activates the domain once nameservers have propagated",
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["domain"],
                "properties": {
                  "domain": { "type": "string", "example": "example.com" }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Domain onboarded. Set the returned nameservers at your registrar, then call verify.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "integer", "example": 123 },
                    "domain": { "type": "string", "example": "example.com" },
                    "status": { "type": "string", "example": "nameservers_pending" },
                    "created_at": { "type": "string", "format": "date-time" },
                    "nameservers": {
                      "type": "array",
                      "items": { "type": "string" },
                      "example": ["ns1.coldmailns.com", "ns2.coldmailns.com"]
                    },
                    "instructions": {
                      "type": "object",
                      "properties": {
                        "action": { "type": "string" },
                        "note": { "type": "string" },
                        "verify": { "type": "string" }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "409": {
            "description": "Domain already exists in the system.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" },
                "example": { "error": "Domain already exists in the system" }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": {
            "description": "Failed to onboard domain with the DNS provider. Safe to retry.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "503": {
            "description": "DNS provider unavailable. Safe to retry.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          }
        }
      }
    },
    "/v1/domains/{domain_id}": {
      "get": {
        "tags": ["Domains"],
        "operationId": "getDomain",
        "summary": "Get domain details",
        "description": "Returns full details for a single domain including status, nameservers, and the recommended next action.",
        "parameters": [{ "$ref": "#/components/parameters/DomainId" }],
        "responses": {
          "200": {
            "description": "Domain details.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/DomainDetail" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "delete": {
        "tags": ["Domains"],
        "operationId": "deleteDomain",
        "summary": "Delete a dangling domain",
        "description": "Deletes a domain that is **not active** and has **zero mailboxes** attached. Also removes the managed DNS zone if one was created.\n\n**Active domains cannot be deleted via the API.** Once a domain reaches `active` status, deletion requires contacting support at support@coldmail.app.",
        "parameters": [{ "$ref": "#/components/parameters/DomainId" }],
        "responses": {
          "200": {
            "description": "Domain deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deleted": { "type": "boolean", "example": true },
                    "id": { "type": "integer", "example": 123 },
                    "domain": { "type": "string", "example": "example.com" },
                    "cloudflare_zone_removed": { "type": "boolean", "example": true },
                    "cloudflare_warning": {
                      "type": "string",
                      "description": "Present only if the managed DNS zone could not be removed."
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "409": {
            "description": "Domain is active or still has mailboxes attached.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" },
                "example": {
                  "error": "Cannot delete an active domain. Only dangling domains (not yet active) can be deleted."
                }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/domains/{domain_id}/dns-template": {
      "get": {
        "tags": ["Domains"],
        "operationId": "getDnsTemplate",
        "summary": "Get DNS template (nameservers)",
        "parameters": [{ "$ref": "#/components/parameters/DomainId" }],
        "responses": {
          "200": {
            "description": "Nameservers and setup instructions for the domain.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domain_id": { "type": "integer", "example": 123 },
                    "domain": { "type": "string", "example": "example.com" },
                    "nameservers": {
                      "type": "array",
                      "items": { "type": "string" },
                      "example": ["ns1.coldmailns.com", "ns2.coldmailns.com"]
                    },
                    "instructions": {
                      "type": "object",
                      "properties": {
                        "setup": { "type": "string" },
                        "note": { "type": "string" },
                        "status": { "type": "string" }
                      }
                    },
                    "managed_by": { "type": "string", "example": "Coldmail via Cloudflare" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/domains/{domain_id}/verify": {
      "post": {
        "tags": ["Domains"],
        "operationId": "verifyDomain",
        "summary": "Verify domain nameservers",
        "description": "Checks that your registrar nameservers point at the managed DNS zone. On success the domain becomes `active` and email DNS records (MX, SPF, DKIM, DMARC) are applied automatically.",
        "parameters": [
          { "$ref": "#/components/parameters/DomainId" },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "responses": {
          "200": {
            "description": "Nameservers verified — domain activated and DNS records applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "integer", "example": 123 },
                    "domain": { "type": "string", "example": "example.com" },
                    "status": { "type": "string", "example": "verified" },
                    "verified_at": { "type": "string", "format": "date-time" },
                    "dns_application": {
                      "type": ["object", "null"],
                      "properties": {
                        "success": { "type": "boolean" },
                        "recordsCreated": { "type": "integer" },
                        "recordsFailed": { "type": "integer" },
                        "errors": { "type": "array", "items": { "type": "string" } }
                      }
                    },
                    "message": {
                      "type": "string",
                      "example": "Domain nameservers verified successfully. Applied 5 DNS records automatically."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Nameservers not yet updated or not yet propagated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "integer", "example": 123 },
                    "domain": { "type": "string", "example": "example.com" },
                    "status": { "type": "string", "example": "pending_dns" },
                    "message": {
                      "type": "string",
                      "example": "Nameservers not yet updated. Please update your domain nameservers and try again."
                    },
                    "expected_nameservers": {
                      "type": "array",
                      "items": { "type": "string" },
                      "example": ["ns1.coldmailns.com", "ns2.coldmailns.com"]
                    },
                    "current_nameservers": {
                      "type": "array",
                      "items": { "type": "string" },
                      "example": []
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes": {
      "get": {
        "tags": ["Mailboxes"],
        "operationId": "listMailboxes",
        "summary": "List mailboxes",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Filter by status, e.g. `active`, `provisioning`, `paused`.",
            "schema": { "type": "string", "example": "active" }
          },
          {
            "name": "domain",
            "in": "query",
            "description": "Filter by domain name.",
            "schema": { "type": "string", "example": "example.com" }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 100, max 100).",
            "schema": { "type": "integer", "default": 100, "maximum": 100 }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Pagination offset.",
            "schema": { "type": "integer", "default": 0 }
          }
        ],
        "responses": {
          "200": {
            "description": "Mailboxes in your organization, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": { "$ref": "#/components/schemas/Mailbox" }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "tags": ["Mailboxes"],
        "operationId": "createMailboxes",
        "summary": "Create mailboxes (batch)",
        "description": "Creates up to 100 mailboxes in one request. Each email's domain must already be purchased/connected and belong to your account.\n\n**Important constraints:**\n- Mailboxes can only be added to a domain **once** — domain locking applies after the first batch.\n- The first **100 mailboxes** (across all domains/orgs) are **free**.\n- Additional mailboxes are billed at $3.00/mo (monthly) or $1.99/mo billed yearly (annual) from your wallet.",
        "parameters": [{ "$ref": "#/components/parameters/IdempotencyKey" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["items"],
                "properties": {
                  "items": {
                    "type": "array",
                    "maxItems": 100,
                    "items": {
                      "type": "object",
                      "required": ["email"],
                      "properties": {
                        "email": { "type": "string", "format": "email", "example": "alice@example.com" }
                      }
                    }
                  },
                  "billing_type": {
                    "type": "string",
                    "enum": ["monthly", "annual"],
                    "default": "monthly"
                  }
                }
              },
              "example": {
                "items": [{ "email": "alice@example.com" }, { "email": "bob@example.com" }],
                "billing_type": "monthly"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Mailboxes created (possibly partially — check `errors`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "created": { "type": "integer", "example": 2 },
                    "failed": { "type": "integer", "example": 0 },
                    "included_free": { "type": "integer", "example": 2 },
                    "additional_paid": { "type": "integer", "example": 0 },
                    "total_cost": { "type": "number", "example": 0 },
                    "billing_type": { "type": "string", "example": "monthly" },
                    "cost_per_additional_mailbox": { "type": "number", "example": 3.0 },
                    "mailboxes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "integer", "example": 456 },
                          "email": { "type": "string", "example": "alice@example.com" },
                          "status": { "type": "string", "example": "pending" },
                          "domain": { "type": "string", "example": "example.com" },
                          "cost": { "type": "number", "example": 0 }
                        }
                      }
                    },
                    "errors": {
                      "type": "array",
                      "description": "Present only when some items failed.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "email": { "type": "string" },
                          "error": { "type": "string" }
                        }
                      }
                    },
                    "message": { "type": "string", "example": "Successfully created 2 mailboxes (free tier)" }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No valid mailboxes to create, or validation failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "string", "example": "No valid mailboxes to create" },
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "email": { "type": "string" },
                          "error": { "type": "string" }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": {
            "description": "Insufficient wallet balance for additional mailboxes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "string", "example": "Insufficient wallet balance" },
                    "required": { "type": "number", "example": 6.0 },
                    "current_balance": { "type": "number", "example": 2.5 },
                    "mailboxes_requested": { "type": "integer", "example": 3 },
                    "included_free": { "type": "integer", "example": 1 },
                    "additional_paid": { "type": "integer", "example": 2 },
                    "cost_per_mailbox": { "type": "number", "example": 3.0 },
                    "billing_type": { "type": "string", "example": "monthly" }
                  }
                }
              }
            }
          },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes/{mailbox_id}": {
      "get": {
        "tags": ["Mailboxes"],
        "operationId": "getMailbox",
        "summary": "Get mailbox details",
        "parameters": [{ "$ref": "#/components/parameters/MailboxId" }],
        "responses": {
          "200": {
            "description": "Mailbox details.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Mailbox" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "patch": {
        "tags": ["Mailboxes"],
        "operationId": "updateMailbox",
        "summary": "Pause or resume a mailbox",
        "parameters": [
          { "$ref": "#/components/parameters/MailboxId" },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["action"],
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": ["pause", "resume"],
                    "example": "pause"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Action applied.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "integer", "example": 456 },
                    "email": { "type": "string", "example": "alice@example.com" },
                    "status": { "type": "string", "example": "paused" },
                    "action": { "type": "string", "example": "pause" },
                    "message": { "type": "string", "example": "Mailbox pause successful" }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid action.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" },
                "example": { "error": "Invalid action. Supported actions: pause, resume" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes/{mailbox_id}/connection": {
      "get": {
        "tags": ["Mailboxes"],
        "operationId": "getMailboxConnection",
        "summary": "Get connection details",
        "description": "Returns IMAP/SMTP connection details and the app password for an **active** mailbox.",
        "parameters": [{ "$ref": "#/components/parameters/MailboxId" }],
        "responses": {
          "200": {
            "description": "Connection details.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mailbox_id": { "type": "integer", "example": 456 },
                    "email": { "type": "string", "example": "alice@example.com" },
                    "status": { "type": "string", "example": "active" },
                    "connection": {
                      "type": "object",
                      "properties": {
                        "imap": {
                          "type": "object",
                          "properties": {
                            "host": { "type": "string", "example": "imap.gmail.com" },
                            "port": { "type": "integer", "example": 993 },
                            "security": { "type": "string", "example": "SSL/TLS" },
                            "username": { "type": "string", "example": "alice@example.com" }
                          }
                        },
                        "smtp": {
                          "type": "object",
                          "properties": {
                            "host": { "type": "string", "example": "smtp.gmail.com" },
                            "port": { "type": "integer", "example": 587 },
                            "security": { "type": "string", "example": "STARTTLS" },
                            "username": { "type": "string", "example": "alice@example.com" }
                          }
                        },
                        "app_password": { "type": "string" },
                        "notes": { "type": "array", "items": { "type": "string" } }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Mailbox not active yet.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "string", "example": "Mailbox not ready" },
                    "status": { "type": "string", "example": "provisioning" },
                    "message": { "type": "string", "example": "Mailbox must be active to get connection details" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes/{mailbox_id}/health": {
      "get": {
        "tags": ["Warmup & Health"],
        "operationId": "getMailboxHealth",
        "summary": "Get mailbox health",
        "description": "Returns the warm-up score (0–100), risk assessment, and recommended daily sending volume for a mailbox.",
        "parameters": [{ "$ref": "#/components/parameters/MailboxId" }],
        "responses": {
          "200": {
            "description": "Health report.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mailbox_id": { "type": "integer", "example": 456 },
                    "email": { "type": "string", "example": "alice@example.com" },
                    "health": {
                      "type": "object",
                      "properties": {
                        "warmup_score": { "type": "integer", "example": 75 },
                        "risk_level": { "type": "string", "enum": ["low", "medium", "high"], "example": "low" },
                        "risk_factors": { "type": "array", "items": { "type": "string" }, "example": [] },
                        "days_active": { "type": "integer", "example": 15 },
                        "status": { "type": "string", "example": "active" },
                        "warmup_enabled": { "type": "boolean", "example": true },
                        "current_daily_volume": { "type": "integer", "example": 30 },
                        "recommended_daily_volume": { "type": "integer", "example": 20 },
                        "last_updated": { "type": "string", "format": "date-time" }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes/{mailbox_id}/warmup": {
      "get": {
        "tags": ["Warmup & Health"],
        "operationId": "getWarmupConfig",
        "summary": "Get warm-up configuration",
        "description": "Returns the current warm-up settings and live stats for a mailbox. If the mailbox is not yet connected to the warm-up service, `connected` is `false`.",
        "parameters": [{ "$ref": "#/components/parameters/MailboxId" }],
        "responses": {
          "200": {
            "description": "Warm-up configuration and stats.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mailbox_id": { "type": "integer", "example": 456 },
                    "email": { "type": "string", "example": "alice@example.com" },
                    "connected": { "type": "boolean", "example": true },
                    "enabled": { "type": "boolean", "example": true },
                    "settings": {
                      "type": "object",
                      "description": "Present when the mailbox is connected and settings could be retrieved.",
                      "properties": {
                        "daily_limit": { "type": "integer", "example": 40 },
                        "warmup_start_volume": { "type": "integer", "example": 3 },
                        "warmup_daily_increase": { "type": "integer", "example": 2 },
                        "warmup_reply_rate": { "type": "number", "example": 30 },
                        "warmup_language": { "type": "string", "example": "English" },
                        "warmup_topic": { "type": "string", "example": "Business" },
                        "sent_today": { "type": "integer", "example": 12 },
                        "received_today": { "type": "integer", "example": 4 },
                        "deliverability_score": { "type": "number", "example": 85 }
                      }
                    },
                    "message": {
                      "type": "string",
                      "description": "Present when the mailbox is not connected or settings could not be retrieved."
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "tags": ["Warmup & Health"],
        "operationId": "configureWarmup",
        "summary": "Configure warm-up",
        "description": "Enables, disables, or updates warm-up for a mailbox. Enabling warm-up requires an available warm-up seat on your plan.\n\nIf the mailbox is not yet connected to the warm-up service, the first call provisions the connection (response `status: \"provisioning\"`) — re-call the endpoint a few seconds later to apply settings.",
        "parameters": [
          { "$ref": "#/components/parameters/MailboxId" },
          { "$ref": "#/components/parameters/IdempotencyKey" }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": { "type": "boolean", "default": true },
                  "daily_limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1000,
                    "description": "Maximum warm-up emails per day."
                  },
                  "warmup_start_volume": { "type": "integer", "minimum": 0 },
                  "warmup_daily_increase": { "type": "integer", "minimum": 0 },
                  "warmup_reply_rate": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100,
                    "description": "Target reply rate percentage."
                  },
                  "warmup_language": { "type": "string", "example": "English" },
                  "warmup_topic": { "type": "string", "example": "Business" }
                }
              },
              "example": {
                "enabled": true,
                "daily_limit": 40,
                "warmup_start_volume": 3,
                "warmup_daily_increase": 2,
                "warmup_reply_rate": 30
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Warm-up configuration updated (or provisioning started on first call).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mailbox_id": { "type": "integer", "example": 456 },
                    "email": { "type": "string", "example": "alice@example.com" },
                    "enabled": { "type": "boolean", "example": true },
                    "status": {
                      "type": "string",
                      "description": "`provisioning` on first call while the warm-up connection is being created."
                    },
                    "sendscale_id": { "type": ["string", "null"] },
                    "settings": {
                      "type": "object",
                      "description": "Echo of the settings that were applied."
                    },
                    "message": { "type": "string", "example": "Warmup configuration updated successfully" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "402": {
            "description": "Warm-up seat limit reached.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "string", "example": "Warmup seat limit reached" },
                    "details": {
                      "type": "object",
                      "properties": {
                        "purchased": { "type": "integer" },
                        "used": { "type": "integer" },
                        "requested": { "type": "integer" },
                        "available": { "type": "integer" }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/send": {
      "post": {
        "tags": ["Sending"],
        "operationId": "sendEmail",
        "summary": "Send email (auto-select mailbox)",
        "description": "**Recommended.** Automatically selects the best available mailbox using round-robin logic, distributes load across mailboxes, and retries with an alternative mailbox if the selected one is rate-limited. Optionally constrain selection by `domain` or `excludeMailboxIds`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["to", "subject"],
                "properties": {
                  "to": {
                    "description": "Recipient email address(es) — string or array.",
                    "oneOf": [
                      { "type": "string", "format": "email" },
                      { "type": "array", "items": { "type": "string", "format": "email" } }
                    ]
                  },
                  "subject": { "type": "string" },
                  "text": {
                    "type": "string",
                    "description": "Plain text content. At least one of `text` or `html` is required."
                  },
                  "html": {
                    "type": "string",
                    "description": "HTML content. A tracking pixel is injected automatically. At least one of `text` or `html` is required."
                  },
                  "cc": {
                    "description": "CC recipients — string or array.",
                    "oneOf": [
                      { "type": "string", "format": "email" },
                      { "type": "array", "items": { "type": "string", "format": "email" } }
                    ]
                  },
                  "bcc": {
                    "description": "BCC recipients — string or array.",
                    "oneOf": [
                      { "type": "string", "format": "email" },
                      { "type": "array", "items": { "type": "string", "format": "email" } }
                    ]
                  },
                  "replyTo": { "type": "string", "format": "email" },
                  "domain": {
                    "type": "string",
                    "description": "Restrict mailbox selection to this domain.",
                    "example": "example.com"
                  },
                  "excludeMailboxIds": {
                    "type": "array",
                    "items": { "type": "integer" },
                    "description": "Mailbox IDs to skip during selection."
                  },
                  "attachments": {
                    "type": "array",
                    "items": { "$ref": "#/components/schemas/Attachment" }
                  }
                }
              },
              "example": {
                "to": "recipient@example.com",
                "subject": "Your email subject",
                "html": "<p>HTML content</p>",
                "domain": "example.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email sent.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SendResult" }
              }
            }
          },
          "400": {
            "description": "Validation error or the send failed.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": {
            "description": "No available mailboxes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "string", "example": "No available mailboxes found" },
                    "message": {
                      "type": "string",
                      "example": "You need at least one active mailbox with SMTP configured to send emails"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "All mailboxes are rate-limited or unavailable (also returned when the API client rate limit is exceeded).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": { "type": "string", "example": "All mailboxes are rate-limited or unavailable" },
                    "message": { "type": "string", "example": "Rate limit exceeded. Daily limit: 500, Hourly limit: 50" },
                    "retry_after": { "type": "string", "format": "date-time" }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": ["Sending"],
        "operationId": "getSendStatus",
        "summary": "Get send status across all mailboxes",
        "responses": {
          "200": {
            "description": "Whether sending is possible and the account limits.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "can_send": { "type": "boolean", "example": true },
                    "available_mailboxes": { "type": "integer", "example": 5 },
                    "limits": { "$ref": "#/components/schemas/SendLimits" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes/{mailbox_id}/send": {
      "post": {
        "tags": ["Sending"],
        "operationId": "sendEmailFromMailbox",
        "summary": "Send email from a specific mailbox",
        "description": "Sends through one specific mailbox. Subject to per-mailbox rate limits — prefer `POST /v1/send` if you don't need to control the sender.",
        "parameters": [{ "$ref": "#/components/parameters/MailboxId" }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["to", "subject"],
                "properties": {
                  "to": {
                    "description": "Recipient email address(es) — string or array.",
                    "oneOf": [
                      { "type": "string", "format": "email" },
                      { "type": "array", "items": { "type": "string", "format": "email" } }
                    ]
                  },
                  "subject": { "type": "string" },
                  "text": {
                    "type": "string",
                    "description": "Plain text content. At least one of `text` or `html` is required."
                  },
                  "html": {
                    "type": "string",
                    "description": "HTML content. A tracking pixel is injected automatically. At least one of `text` or `html` is required."
                  },
                  "cc": {
                    "oneOf": [
                      { "type": "string", "format": "email" },
                      { "type": "array", "items": { "type": "string", "format": "email" } }
                    ]
                  },
                  "bcc": {
                    "oneOf": [
                      { "type": "string", "format": "email" },
                      { "type": "array", "items": { "type": "string", "format": "email" } }
                    ]
                  },
                  "replyTo": { "type": "string", "format": "email" },
                  "attachments": {
                    "type": "array",
                    "items": { "$ref": "#/components/schemas/Attachment" }
                  }
                }
              },
              "example": {
                "to": "recipient@example.com",
                "subject": "Your email subject",
                "text": "Plain text content"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email sent.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SendResult" }
              }
            }
          },
          "400": {
            "description": "Validation error, mailbox not ready, or rate limit exceeded for this mailbox.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Error" },
                "examples": {
                  "rate_limited": { "value": { "error": "Rate limit exceeded. Try again after 2025-01-15T11:00:00Z" } },
                  "not_ready": { "value": { "error": "Mailbox not found or not ready to send emails" } },
                  "no_content": { "value": { "error": "Either text or html content is required" } }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "get": {
        "tags": ["Sending"],
        "operationId": "getMailboxSendStatus",
        "summary": "Get mailbox send status",
        "parameters": [{ "$ref": "#/components/parameters/MailboxId" }],
        "responses": {
          "200": {
            "description": "Whether this mailbox can send and its limits.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mailbox_id": { "type": "integer", "example": 456 },
                    "email": { "type": "string", "example": "alice@example.com" },
                    "status": { "type": "string", "example": "active" },
                    "can_send": { "type": "boolean", "example": true },
                    "limits": { "$ref": "#/components/schemas/SendLimits" },
                    "smtp_configured": { "type": "boolean", "example": true }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes/rate-limits": {
      "get": {
        "tags": ["Sending"],
        "operationId": "getRateLimits",
        "summary": "Get email rate limits",
        "description": "Returns your plan's sending limits, current usage, and remaining quota.",
        "responses": {
          "200": {
            "description": "Rate limit status.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user_id": { "type": "string", "example": "user_123" },
                    "plan": { "type": "string", "example": "starter" },
                    "limits": { "$ref": "#/components/schemas/SendLimits" },
                    "usage": { "$ref": "#/components/schemas/SendLimits" },
                    "remaining": { "$ref": "#/components/schemas/SendLimits" },
                    "reset_time": { "type": "string", "format": "date-time" },
                    "can_send": { "type": "boolean", "example": true }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes/{mailbox_id}/stats": {
      "get": {
        "tags": ["Analytics & Bounces"],
        "operationId": "getMailboxStats",
        "summary": "Get mailbox email statistics",
        "description": "Send/open/click totals, bounce breakdown, recent emails, and daily volumes for one mailbox.\n\n`total_bounced`/`bounce_rate` cover only emails sent through Coldmail; `external_bounces`/`mailbox_bounce_events` also include bounces visible in the mailbox from sends outside Coldmail.",
        "parameters": [{ "$ref": "#/components/parameters/MailboxId" }],
        "responses": {
          "200": {
            "description": "Mailbox statistics.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mailbox_id": { "type": "integer", "example": 456 },
                    "email": { "type": "string", "example": "alice@example.com" },
                    "stats": {
                      "type": "object",
                      "properties": {
                        "total_sent": { "type": "integer", "example": 150 },
                        "total_opened": { "type": "integer", "example": 45 },
                        "total_clicked": { "type": "integer", "example": 12 },
                        "open_rate": { "type": "number", "example": 30.0 },
                        "click_rate": { "type": "number", "example": 8.0 },
                        "total_bounced": { "type": "integer", "example": 2 },
                        "bounce_rate": { "type": "number", "example": 1.33 },
                        "platform_bounced": { "type": "integer", "example": 2 },
                        "external_bounces": { "type": "integer", "example": 6 },
                        "mailbox_bounce_events": { "type": "integer", "example": 8 },
                        "bounce_breakdown": { "$ref": "#/components/schemas/BounceBreakdown" },
                        "bounce_events": {
                          "type": "object",
                          "properties": {
                            "total_events": { "type": "integer", "example": 8 },
                            "platform_bounced": { "type": "integer", "example": 2 },
                            "external_or_unknown": { "type": "integer", "example": 6 },
                            "by_scope": { "type": "object", "additionalProperties": { "type": "integer" } },
                            "by_source": { "type": "object", "additionalProperties": { "type": "integer" } },
                            "by_confidence": { "type": "object", "additionalProperties": { "type": "integer" } }
                          }
                        },
                        "recent_emails": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": { "type": "integer", "example": 123 },
                              "recipient": { "type": "string", "example": "customer@example.com" },
                              "subject": { "type": "string", "example": "Welcome to our service" },
                              "sent_at": { "type": "string", "format": "date-time" },
                              "status": { "type": "string", "example": "sent" },
                              "tracking_pixel_id": { "type": ["string", "null"] },
                              "opened": { "type": "boolean", "example": true },
                              "opened_at": { "type": ["string", "null"], "format": "date-time" },
                              "opened_ip": { "type": ["string", "null"], "example": "192.168.1.1" }
                            }
                          }
                        },
                        "daily_stats": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": { "type": "string", "example": "2025-01-15" },
                              "emails_sent": { "type": "integer", "example": 25 }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes/stats": {
      "get": {
        "tags": ["Analytics & Bounces"],
        "operationId": "getOverallStats",
        "summary": "Get overall email statistics",
        "description": "Org-wide send/open/click/bounce totals, a paginated per-mailbox breakdown, and a daily summary.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Max mailbox rows (default 50).",
            "schema": { "type": "integer", "default": 50 }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Pagination offset.",
            "schema": { "type": "integer", "default": 0 }
          }
        ],
        "responses": {
          "200": {
            "description": "Organization-wide statistics.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "org_id": { "type": "string", "example": "org_abc123" },
                    "totals": {
                      "type": "object",
                      "properties": {
                        "total_sent": { "type": "integer", "example": 500 },
                        "total_opened": { "type": "integer", "example": 150 },
                        "total_clicked": { "type": "integer", "example": 40 },
                        "open_rate": { "type": "number", "example": 30.0 },
                        "click_rate": { "type": "number", "example": 8.0 },
                        "total_bounced": { "type": "integer", "example": 5 },
                        "bounce_rate": { "type": "number", "example": 1.0 },
                        "platform_bounced": { "type": "integer", "example": 5 },
                        "external_bounces": { "type": "integer", "example": 34 },
                        "mailbox_bounce_events": { "type": "integer", "example": 39 },
                        "bounce_breakdown": { "$ref": "#/components/schemas/BounceBreakdown" }
                      }
                    },
                    "mailboxes": {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "mailbox_id": { "type": "integer", "example": 456 },
                              "email": { "type": "string", "example": "alice@example.com" },
                              "total_sent": { "type": "integer", "example": 200 },
                              "total_opened": { "type": "integer", "example": 60 },
                              "open_rate": { "type": "number", "example": 30.0 },
                              "total_bounced": { "type": "integer", "example": 3 },
                              "bounce_rate": { "type": "number", "example": 1.5 },
                              "platform_bounced": { "type": "integer", "example": 3 },
                              "external_bounces": { "type": "integer", "example": 7 },
                              "mailbox_bounce_events": { "type": "integer", "example": 10 }
                            }
                          }
                        },
                        "pagination": { "$ref": "#/components/schemas/Pagination" }
                      }
                    },
                    "daily_summary": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": { "type": "string", "example": "2025-01-15" },
                          "sent": { "type": "integer", "example": 50 },
                          "opened": { "type": "integer", "example": 15 },
                          "clicked": { "type": "integer", "example": 4 },
                          "bounced": { "type": "integer", "example": 1 }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/mailboxes/{mailbox_id}/bounces": {
      "get": {
        "tags": ["Analytics & Bounces"],
        "operationId": "getMailboxBounces",
        "summary": "Get bounce summary and list",
        "parameters": [
          { "$ref": "#/components/parameters/MailboxId" },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by bounce type.",
            "schema": {
              "type": "string",
              "enum": [
                "smtp_hard_bounce",
                "smtp_soft_bounce",
                "dsn_hard_bounce",
                "dsn_soft_bounce",
                "provider_bounce",
                "inbox_ai_bounce",
                "manual_bounce",
                "unknown_bounce"
              ]
            }
          },
          {
            "name": "scope",
            "in": "query",
            "description": "Filter by bounce scope.",
            "schema": { "type": "string", "enum": ["platform_sent", "external_or_unknown"] }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max results (default 50, max 100).",
            "schema": { "type": "integer", "default": 50, "maximum": 100 }
          },
          {
            "name": "offset",
            "in": "query",
            "description": "Pagination offset.",
            "schema": { "type": "integer", "default": 0 }
          }
        ],
        "responses": {
          "200": {
            "description": "Bounce summary and paginated bounce events.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mailbox_id": { "type": "integer", "example": 456 },
                    "email": { "type": "string", "example": "alice@example.com" },
                    "summary": {
                      "type": "object",
                      "properties": {
                        "total_sent": { "type": "integer", "example": 150 },
                        "total_bounced": { "type": "integer", "example": 2 },
                        "bounce_rate": { "type": "number", "example": 1.33 },
                        "platform_bounced": { "type": "integer", "example": 2 },
                        "external_bounces": { "type": "integer", "example": 6 },
                        "mailbox_bounce_events": { "type": "integer", "example": 8 },
                        "breakdown": { "$ref": "#/components/schemas/BounceBreakdown" },
                        "by_scope": { "type": "object", "additionalProperties": { "type": "integer" } },
                        "by_source": { "type": "object", "additionalProperties": { "type": "integer" } }
                      }
                    },
                    "bounces": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/BounceEvent" }
                    },
                    "pagination": { "$ref": "#/components/schemas/Pagination" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      },
      "post": {
        "tags": ["Analytics & Bounces"],
        "operationId": "scanMailboxBounces",
        "summary": "Trigger on-demand bounce scan",
        "description": "Scans the mailbox INBOX via IMAP right now for DSN bounce emails, instead of waiting for the hourly background scan.",
        "parameters": [
          { "$ref": "#/components/parameters/MailboxId" },
          { "$ref": "#/components/parameters/IdempotencyKey" },
          {
            "name": "lookback_days",
            "in": "query",
            "description": "How many days back to scan (default 7, max 30).",
            "schema": { "type": "integer", "default": 7, "maximum": 30 }
          }
        ],
        "responses": {
          "200": {
            "description": "Scan finished.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "mailbox_id": { "type": "integer", "example": 456 },
                    "email": { "type": "string", "example": "alice@example.com" },
                    "scan": {
                      "type": "object",
                      "properties": {
                        "mailboxEmail": { "type": "string", "example": "alice@example.com" },
                        "scanned": {
                          "type": "integer",
                          "description": "DSN/mailer-daemon emails found in INBOX.",
                          "example": 5
                        },
                        "processed": {
                          "type": "integer",
                          "description": "Matched to a sent email and marked as bounced.",
                          "example": 2
                        },
                        "externalRecorded": {
                          "type": "integer",
                          "description": "Recorded as external bounce events.",
                          "example": 1
                        },
                        "skipped": {
                          "type": "integer",
                          "description": "Already processed or no matching sent email.",
                          "example": 3
                        },
                        "errors": {
                          "type": "array",
                          "items": { "type": "string" },
                          "description": "Non-fatal IMAP or parse errors."
                        }
                      }
                    },
                    "message": {
                      "type": "string",
                      "example": "Scan complete. Found 5 DSN emails, processed 2 new bounces."
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/v1/pixels/{pixel_id}": {
      "get": {
        "tags": ["Analytics & Bounces"],
        "operationId": "getPixelStats",
        "summary": "Get tracking pixel statistics",
        "description": "Open and click details for a single tracked email. Only available for HTML emails — plain text sends return `trackingPixelId: null` in the send response.",
        "parameters": [
          {
            "name": "pixel_id",
            "in": "path",
            "required": true,
            "description": "The `trackingPixelId` returned by a send operation.",
            "schema": { "type": "string", "format": "uuid" }
          }
        ],
        "responses": {
          "200": {
            "description": "Pixel statistics.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "pixel_id": { "type": "string", "format": "uuid" },
                    "email_log": {
                      "type": "object",
                      "properties": {
                        "id": { "type": "integer", "example": 54 },
                        "recipient": { "type": "string", "example": "customer@example.com" },
                        "subject": { "type": "string", "example": "Welcome to our service" },
                        "sent_at": { "type": "string", "format": "date-time" },
                        "status": { "type": "string", "example": "sent" },
                        "mailbox_id": { "type": "integer", "example": 199 },
                        "mailbox_email": { "type": "string", "example": "alice@example.com" }
                      }
                    },
                    "stats": {
                      "type": "object",
                      "properties": {
                        "opened": { "type": "boolean", "example": true },
                        "opened_at": { "type": ["string", "null"], "format": "date-time" },
                        "opened_ip": { "type": ["string", "null"], "example": "192.168.1.1" },
                        "opened_user_agent": { "type": ["string", "null"] },
                        "opened_location": {
                          "type": "object",
                          "properties": {
                            "country": { "type": ["string", "null"], "example": "US" },
                            "city": { "type": ["string", "null"], "example": "New York" }
                          }
                        },
                        "total_opens": { "type": "integer", "example": 1 },
                        "clicks": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "url": { "type": "string", "example": "https://example.com" },
                              "clicked_at": { "type": "string", "format": "date-time" },
                              "ip_address": { "type": ["string", "null"] },
                              "user_agent": { "type": ["string", "null"] }
                            }
                          }
                        },
                        "total_clicks": { "type": "integer", "example": 1 }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    }
  },
  "webhooks": {
    "mailbox.status.changed": {
      "post": {
        "summary": "Mailbox status changed",
        "description": "Sent when a mailbox transitions between statuses (e.g. `pending` → `active`). Webhook endpoints are registered from the dashboard. Every delivery is signed — see *Webhooks* in the introduction.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/WebhookEvent" },
              "example": {
                "id": "evt_123",
                "type": "mailbox.status.changed",
                "data": {
                  "mailbox_id": 456,
                  "email": "alice@example.com",
                  "old_status": "pending",
                  "new_status": "active",
                  "timestamp": "2025-01-15T10:00:00Z"
                },
                "timestamp": "2025-01-15T10:00:00Z",
                "apiClientId": "client_123"
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Return any 2xx status to acknowledge receipt." }
        }
      }
    },
    "warmup.score.updated": {
      "post": {
        "summary": "Warm-up score updated",
        "description": "Sent when a mailbox's warm-up score changes.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/WebhookEvent" },
              "example": {
                "id": "evt_124",
                "type": "warmup.score.updated",
                "data": {
                  "mailbox_id": 456,
                  "email": "alice@example.com",
                  "old_score": 70,
                  "new_score": 75,
                  "risk_level": "low",
                  "timestamp": "2025-01-15T10:00:00Z"
                },
                "timestamp": "2025-01-15T10:00:00Z",
                "apiClientId": "client_123"
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Return any 2xx status to acknowledge receipt." }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Format: `ApiKey <client_id>:<api_key>`\n\nCreate credentials from the dashboard under **Integrations**. The client ID starts with `user_`.\n\nExample:\n```\nAuthorization: ApiKey user_abc123:cm_sk_xxxxxxxx\n```"
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "A UUID that uniquely identifies this operation. Required for all write operations to prevent duplicates.",
        "schema": {
          "type": "string",
          "format": "uuid",
          "example": "9b2f6c1e-8a4d-4f3b-9c2a-1d5e7f8a9b0c"
        }
      },
      "DomainId": {
        "name": "domain_id",
        "in": "path",
        "required": true,
        "description": "Numeric domain ID.",
        "schema": { "type": "integer", "example": 123 }
      },
      "MailboxId": {
        "name": "mailbox_id",
        "in": "path",
        "required": true,
        "description": "Numeric mailbox ID.",
        "schema": { "type": "integer", "example": 456 }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Validation error.",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/Error" } }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid API credentials.",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": { "error": "Invalid API credentials" }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found (or not owned by your organization).",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": { "error": "Not found" }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded (60 requests per minute per API client).",
        "headers": {
          "X-RateLimit-Limit": {
            "description": "Requests allowed per minute.",
            "schema": { "type": "integer", "example": 60 }
          },
          "X-RateLimit-Remaining": {
            "description": "Requests remaining in the current window.",
            "schema": { "type": "integer", "example": 0 }
          },
          "X-RateLimit-Reset": {
            "description": "When the current window resets.",
            "schema": { "type": "string" }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": { "type": "string", "example": "Rate limit exceeded" },
                "retry_after": {
                  "type": "integer",
                  "description": "Seconds until the rate limit window resets.",
                  "example": 30
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": { "type": "string", "example": "Detailed error message" }
        }
      },
      "Domain": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 123 },
          "domain": { "type": "string", "example": "example.com" },
          "status": {
            "type": "string",
            "description": "Lifecycle status: `pending_dns`, `nameservers_pending`, `nameservers_updated`, `active`, or `failed`.",
            "example": "active"
          },
          "error_message": { "type": ["string", "null"] },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "DomainDetail": {
        "allOf": [
          { "$ref": "#/components/schemas/Domain" },
          {
            "type": "object",
            "properties": {
              "nameservers_verified": { "type": "boolean", "example": true },
              "nameservers": {
                "type": "array",
                "items": { "type": "string" },
                "example": ["ns1.coldmailns.com", "ns2.coldmailns.com"]
              },
              "next_action": {
                "type": "string",
                "description": "Present when an action is required to finish setup.",
                "example": "POST /v1/domains/123/verify — call once you have updated your registrar nameservers."
              }
            }
          }
        ]
      },
      "Mailbox": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 456 },
          "email": { "type": "string", "example": "alice@example.com" },
          "username": { "type": "string", "example": "alice" },
          "firstname": { "type": ["string", "null"], "example": "Alice" },
          "lastname": { "type": ["string", "null"], "example": "Smith" },
          "display_name": { "type": "string", "example": "alice@example.com" },
          "status": {
            "type": "string",
            "description": "Lifecycle status: `pending`, `provisioning`, `active`, or `paused`.",
            "example": "active"
          },
          "domain": { "type": "string", "example": "example.com" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" },
          "quota": {
            "type": "object",
            "properties": {
              "daily_send_cap": { "type": "integer", "example": 30 }
            }
          }
        }
      },
      "Attachment": {
        "type": "object",
        "required": ["filename", "content"],
        "properties": {
          "filename": { "type": "string", "example": "document.pdf" },
          "content": {
            "type": "string",
            "description": "Base64-encoded file content.",
            "example": "JVBERi0xLjQK..."
          },
          "contentType": { "type": "string", "example": "application/pdf" }
        }
      },
      "SendResult": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "messageId": { "type": "string", "example": "<message-id@mail.gmail.com>" },
          "mailbox_id": { "type": "integer", "example": 456 },
          "mailbox_email": {
            "type": "string",
            "description": "Present on unified sends — the auto-selected sender.",
            "example": "sender@example.com"
          },
          "sent_at": { "type": "string", "format": "date-time" },
          "emailLogId": {
            "type": "integer",
            "description": "Use to look up this email in statistics.",
            "example": 123
          },
          "trackingPixelId": {
            "type": ["string", "null"],
            "description": "Query `GET /v1/pixels/{pixel_id}` for open/click stats. `null` for plain text emails.",
            "format": "uuid"
          }
        }
      },
      "SendLimits": {
        "type": "object",
        "properties": {
          "daily": { "type": "integer", "example": 500 },
          "hourly": { "type": "integer", "example": 50 }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "total": { "type": "integer", "example": 12 },
          "limit": { "type": "integer", "example": 50 },
          "offset": { "type": "integer", "example": 0 }
        }
      },
      "BounceBreakdown": {
        "type": "object",
        "description": "Bounce counts by type. SMTP = rejected during send; DSN = bounced after acceptance; inbox_ai/manual = ColdBox-classified.",
        "properties": {
          "smtp_hard_bounce": { "type": "integer", "example": 1 },
          "smtp_soft_bounce": { "type": "integer", "example": 0 },
          "dsn_hard_bounce": { "type": "integer", "example": 2 },
          "dsn_soft_bounce": { "type": "integer", "example": 0 },
          "provider_bounce": { "type": "integer", "example": 0 },
          "inbox_ai_bounce": { "type": "integer", "example": 5 },
          "manual_bounce": { "type": "integer", "example": 1 },
          "unknown_bounce": { "type": "integer", "example": 0 }
        }
      },
      "BounceEvent": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "example": "bounce_event_uuid" },
          "email_log_id": {
            "type": ["integer", "null"],
            "description": "Set when the bounce is tied to a Coldmail send.",
            "example": 6034
          },
          "inbox_thread_id": { "type": ["string", "null"] },
          "inbox_message_id": { "type": ["string", "null"] },
          "source": {
            "type": "string",
            "description": "How the bounce was detected, e.g. `imap_dsn`, `inbox_ai`, `manual_label`.",
            "example": "imap_dsn"
          },
          "scope": {
            "type": "string",
            "enum": ["platform_sent", "external_or_unknown"],
            "example": "platform_sent"
          },
          "confidence": { "type": "string", "example": "high" },
          "original_message_id": { "type": ["string", "null"] },
          "recipient": { "type": ["string", "null"], "example": "nobody@invaliddomain.com" },
          "subject": { "type": ["string", "null"], "example": "Outreach email" },
          "sent_at": { "type": ["string", "null"], "format": "date-time" },
          "bounced_at": { "type": "string", "format": "date-time" },
          "bounce_type": { "type": "string", "example": "dsn_hard_bounce" },
          "bounce_code": { "type": ["string", "null"], "example": "5.4.4" },
          "bounce_reason": {
            "type": ["string", "null"],
            "example": "dns; DNS type 'mx' lookup of invaliddomain.com responded with code NXDOMAIN"
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "example": "evt_123" },
          "type": {
            "type": "string",
            "enum": ["mailbox.status.changed", "warmup.score.updated"]
          },
          "data": {
            "type": "object",
            "description": "Event-specific payload."
          },
          "timestamp": { "type": "string", "format": "date-time" },
          "apiClientId": {
            "type": "string",
            "description": "The API client this event belongs to.",
            "example": "client_123"
          }
        }
      }
    }
  }
}
