{
  "openapi": "3.1.0",
  "info": {
    "title": "Postfleet API",
    "version": "1.0.0",
    "description": "Hand-authored OpenAPI description of the Postfleet `/api/v1/**` REST surface. Every path, method, status code, request field, and error `code` is transcribed from the shipped route handlers under `src/app/api/v1/`; a drift test asserts this file stays in sync with the code. All endpoints authenticate with a bearer `pf_` API key. This spec documents shipped behavior only — see the `/docs` pages for narrative guides and current limitations."
  },
  "servers": [
    {
      "url": "/",
      "description": "Same-origin (relative). Prefix every path with your deployment origin, e.g. https://your-app.example.com"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "send",
      "description": "Direct outbound send with idempotency."
    },
    {
      "name": "messages",
      "description": "Read inbound/outbound messages."
    },
    {
      "name": "drafts",
      "description": "Human-in-the-loop drafts and approvals."
    },
    {
      "name": "mailboxes",
      "description": "Mailbox provisioning (account-plane)."
    },
    {
      "name": "domains",
      "description": "Custom sending-domain management (account-plane, paid plan)."
    }
  ],
  "paths": {
    "/api/v1/send": {
      "post": {
        "operationId": "sendMessage",
        "tags": [
          "send"
        ],
        "summary": "Send an email",
        "description": "The single outbound path for direct and MCP sends. Requires an `api` or `mcp` key with `can_send`. Supply an optional `client_id` for idempotent duplicate protection (replay table). On a mailbox with `require_approval` enabled, the send is turned into a forced draft (`202`) instead of delivering. `to` is required unless `reply_to_message_id` is supplied; `to` must be exactly one address (multi-recipient is rejected `400`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Idempotent replay: this `client_id` was already used with the same payload for a completed send; the stored result is returned verbatim.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendResult"
                }
              }
            }
          },
          "201": {
            "description": "Sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendResult"
                }
              }
            }
          },
          "202": {
            "description": "Mailbox requires approval — the send was queued as a forced draft awaiting a human.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PendingApproval"
                }
              }
            }
          },
          "400": {
            "description": "Validation error (missing `mailbox_id`/`text`, bad `client_id`, `to` not a single address, missing `to` when not replying) or a permanent provider rejection (`{retryable:false}`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "Monthly send quota exhausted (terminal for this `client_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "monthly send quota exhausted"
                }
              }
            }
          },
          "403": {
            "description": "Key cannot send / is scoped to a different mailbox (`code:key_scope`), recipient blocked by a send list (`code:send_blocked_by_list`), or a custom-domain entitlement rejection.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/KeyScopeError"
                    },
                    {
                      "$ref": "#/components/schemas/SendBlockedByListError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Mailbox not found, or (when replying) the original message was not found / not visible to a mailbox-bound key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict: same `client_id` with a different payload (`idempotency_conflict`), or a send with this `client_id` is still in progress (`idempotency_in_progress`).",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/IdempotencyConflictError"
                    },
                    {
                      "$ref": "#/components/schemas/IdempotencyInProgressError"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Recipient is suppressed (bounce/complaint/unsubscribe).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "recipient is suppressed (bounce/complaint/unsubscribe)"
                }
              }
            }
          },
          "502": {
            "description": "Transient delivery failure (`{retryable:true}`) or an ambiguous provider outcome (`code:delivery_outcome_unknown`) — the send may or may not have gone out and is left for reconciliation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/messages": {
      "get": {
        "operationId": "listMessages",
        "tags": [
          "messages"
        ],
        "summary": "List messages in a mailbox",
        "description": "Lists the most recent messages (inbound and outbound) for a mailbox, newest first. Requires an `api` or `mcp` key with `can_read`.",
        "parameters": [
          {
            "name": "mailbox_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Mailbox to list. A mailbox-bound key may only list its own mailbox."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 50
            },
            "description": "Max rows (integer ≥ 1). Values above 100 are clamped to 100."
          }
        ],
        "responses": {
          "200": {
            "description": "Messages.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "messages": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/MessageListItem"
                      }
                    }
                  },
                  "required": [
                    "messages"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "`mailbox_id` query param required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Key cannot read messages, or is scoped to a different mailbox (`code:key_scope`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyScopeError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/messages/{id}": {
      "get": {
        "operationId": "getMessage",
        "tags": [
          "messages"
        ],
        "summary": "Get a message",
        "description": "Returns a single message with body, comprehension, and attachments. Requires `can_read`. A message in another mailbox (for a mailbox-bound key) or another account is reported as `404` (anti-enumeration).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Message.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageDetail"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Key cannot read messages (`code:key_scope`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyScopeError"
                }
              }
            }
          },
          "404": {
            "description": "Message not found (missing, cross-account, or cross-mailbox for a bound key).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "message not found"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/mailboxes": {
      "post": {
        "operationId": "createMailbox",
        "tags": [
          "mailboxes"
        ],
        "summary": "Create a mailbox",
        "description": "Provisions a mailbox. Account-plane: a mailbox-bound key is rejected (`code:key_scope`). Accepts `bootstrap`, `api`, or `mcp` scope. Without `domain_id` the address is `agent-{slug}@{shared-domain}`; with a verified `domain_id` (paid plan) it is `{slug}@{your-domain}`.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMailboxRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Mailbox created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "address": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "address"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid `slug`, or the referenced domain is not verified.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Mailbox-bound key on an account-plane route (`code:key_scope`), or custom domains require a paid plan.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/KeyScopeError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Referenced `extraction_schema_id` or `domain_id` not found for this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/domains": {
      "post": {
        "operationId": "createDomain",
        "tags": [
          "domains"
        ],
        "summary": "Add a custom sending domain",
        "description": "Registers a custom domain with the provider and returns the DNS records to add. Account-plane, paid plan only. Returns `200` (not `201`).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Domain name, e.g. mail.example.com."
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Domain registered; add the returned DNS records to verify it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainCreated"
                }
              }
            }
          },
          "400": {
            "description": "Invalid domain name.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "invalid domain name"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Mailbox-bound key on an account-plane route (`code:key_scope`), or custom domains require a paid plan.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/KeyScopeError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listDomains",
        "tags": [
          "domains"
        ],
        "summary": "List custom domains",
        "description": "Lists this account's custom domains. Account-plane.",
        "responses": {
          "200": {
            "description": "Domains.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domains": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Domain"
                      }
                    }
                  },
                  "required": [
                    "domains"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Mailbox-bound key on an account-plane route (`code:key_scope`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyScopeError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/domains/{id}/verify": {
      "post": {
        "operationId": "verifyDomain",
        "tags": [
          "domains"
        ],
        "summary": "Re-check a domain's verification",
        "description": "Refreshes verification status for a domain from the provider. Account-plane, paid plan only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current verification status.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "status"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Mailbox-bound key on an account-plane route (`code:key_scope`), or custom domains require a paid plan.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/KeyScopeError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Domain not found for this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "not found"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/drafts": {
      "post": {
        "operationId": "createDraft",
        "tags": [
          "drafts"
        ],
        "summary": "Create a draft",
        "description": "Creates a voluntary draft in status `draft`. Requires `can_send`. The draft is not forced into the approval queue at creation time even on a `require_approval` mailbox — forcing happens at send time. `to` is required unless `reply_to_message_id` is supplied. Note: draft creation has no `client_id` idempotency yet — a retried create can duplicate a draft.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Draft created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "const": "draft"
                    }
                  },
                  "required": [
                    "id",
                    "status"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Validation error (missing `mailbox_id`/`text`, bad `client_id`, `to` not a single address, missing `to` when not replying).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Key cannot send, or is scoped to a different mailbox (`code:key_scope`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyScopeError"
                }
              }
            }
          },
          "404": {
            "description": "Mailbox not found, or (when replying) the original message was not found / not visible to a mailbox-bound key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listDrafts",
        "tags": [
          "drafts"
        ],
        "summary": "List open drafts in a mailbox",
        "description": "Lists non-tombstoned, non-terminal drafts for a mailbox. Requires `can_read`.",
        "parameters": [
          {
            "name": "mailbox_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A mailbox-bound key may only list its own mailbox."
          }
        ],
        "responses": {
          "200": {
            "description": "Drafts.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "drafts": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Draft"
                      }
                    }
                  },
                  "required": [
                    "drafts"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "`mailbox_id` query param required.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Key cannot read drafts, or is scoped to a different mailbox (`code:key_scope`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyScopeError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/drafts/{id}": {
      "get": {
        "operationId": "getDraft",
        "tags": [
          "drafts"
        ],
        "summary": "Get a draft",
        "description": "Returns a draft's public shape. Requires `can_read`. Missing, cross-account, cross-mailbox (for a bound key), and tombstoned (sent/rejected/deleted) drafts all collapse to a byte-identical `404` (anti-enumeration).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Draft.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Draft"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Key cannot read drafts (`code:key_scope`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyScopeError"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/DraftNotFound"
          }
        }
      },
      "patch": {
        "operationId": "updateDraft",
        "tags": [
          "drafts"
        ],
        "summary": "Edit a draft's envelope",
        "description": "Merges `to`/`subject`/`text` over the stored draft and re-validates the recipient through the send path's single-recipient guard. Requires `can_send`. The reply context is immutable: supplying `reply_to_message_id` is rejected `400`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDraftRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated draft.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Draft"
                }
              }
            }
          },
          "400": {
            "description": "`reply_to_message_id` cannot be changed, or the merged `to` is not a single address.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Key cannot send (`code:key_scope`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyScopeError"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/DraftNotFound"
          },
          "409": {
            "description": "Draft is no longer editable (already sending or terminal).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalConflictError"
                },
                "example": {
                  "code": "approval_conflict",
                  "error": "draft is no longer editable"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteDraft",
        "tags": [
          "drafts"
        ],
        "summary": "Discard a draft",
        "description": "Soft-deletes a non-terminal draft. Requires `can_send`. Returns `204` on success; `409` if the draft is already sending/sent/rejected.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Draft discarded (no content)."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "description": "Key cannot send (`code:key_scope`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyScopeError"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/DraftNotFound"
          },
          "409": {
            "description": "Draft can no longer be deleted (already sending or terminal).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalConflictError"
                },
                "example": {
                  "code": "approval_conflict",
                  "error": "draft can no longer be deleted"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/drafts/{id}/send": {
      "post": {
        "operationId": "sendDraft",
        "tags": [
          "drafts"
        ],
        "summary": "Send a draft",
        "description": "Sends an agent's own draft. Requires `can_send`. The mailbox's current `require_approval` decides the outcome: when enabled the draft is promoted to `pending_approval` (`202`); when disabled it is delivered through the shared send pipeline (`201`). A draft already queued for a human idempotently returns `202`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Draft sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DraftSendResult"
                }
              }
            }
          },
          "202": {
            "description": "Mailbox requires approval — the draft was queued for a human (or was already queued).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PendingApproval"
                }
              }
            }
          },
          "400": {
            "description": "Permanent provider rejection during delivery (`{retryable:false}`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "description": "Monthly send quota exhausted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": "monthly send quota exhausted"
                }
              }
            }
          },
          "403": {
            "description": "Key cannot send (`code:key_scope`), recipient blocked by a send list (`code:send_blocked_by_list`), or a custom-domain entitlement rejection.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/KeyScopeError"
                    },
                    {
                      "$ref": "#/components/schemas/SendBlockedByListError"
                    },
                    {
                      "$ref": "#/components/schemas/Error"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/DraftNotFound"
          },
          "409": {
            "description": "Draft can no longer be sent (concurrent send/delete/edit moved it out of a sendable state).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalConflictError"
                },
                "example": {
                  "code": "approval_conflict",
                  "error": "draft can no longer be sent"
                }
              }
            }
          },
          "422": {
            "description": "Recipient is suppressed, or the draft has no recipient.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "Transient delivery failure (`{retryable:true}`) or an ambiguous provider outcome (`code:delivery_outcome_unknown`); the draft stays in `sending` for reconciliation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "A Postfleet API key, e.g. `Authorization: Bearer pf_...`. Keys carry a scope (`api`/`mcp`/`bootstrap`), optional mailbox binding, and `can_read`/`can_send` capabilities."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid bearer token, or a key whose scope is not permitted for this endpoint.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "DraftNotFound": {
        "description": "Draft not found (missing, cross-account, cross-mailbox for a bound key, or tombstoned). Byte-identical for every case (anti-enumeration).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": "draft not found"
            }
          }
        }
      }
    },
    "schemas": {
      "SendRequest": {
        "type": "object",
        "properties": {
          "mailbox_id": {
            "type": "string",
            "minLength": 1,
            "description": "Mailbox to send from. A mailbox-bound key must match this."
          },
          "text": {
            "type": "string",
            "minLength": 1,
            "description": "Plain-text body."
          },
          "to": {
            "description": "Single recipient address. Required unless replying; must be exactly one address.",
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "reply_to_message_id": {
            "description": "Reply in-thread to an existing message; resolves `to`/`subject`/thread from the original.",
            "type": "string"
          },
          "client_id": {
            "description": "Idempotency key for duplicate protection. Must not start with `draft:` (reserved).",
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^(?!draft:)"
          }
        },
        "required": [
          "mailbox_id",
          "text"
        ],
        "additionalProperties": false
      },
      "CreateMailboxRequest": {
        "type": "object",
        "properties": {
          "slug": {
            "description": "Local-part slug, `[a-z0-9][a-z0-9-]{0,40}`. Random hex if omitted.",
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9-]{0,40}$"
          },
          "display_name": {
            "type": "string"
          },
          "extraction_schema_id": {
            "description": "Must belong to this account.",
            "type": "string"
          },
          "domain_id": {
            "description": "A verified custom domain (paid plan). Omit to use the shared domain.",
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "UpdateDraftRequest": {
        "type": "object",
        "properties": {
          "to": {
            "description": "New single-recipient address.",
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        },
        "additionalProperties": false,
        "description": "Omitted fields keep the stored value. `reply_to_message_id` is immutable and rejected if supplied."
      },
      "SendResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stored message id."
          },
          "thread_id": {
            "type": "string"
          },
          "provider_message_id": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "thread_id",
          "provider_message_id"
        ],
        "additionalProperties": false
      },
      "DraftSendResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stored message id."
          },
          "draft_id": {
            "type": "string",
            "description": "The now-tombstoned source draft."
          },
          "thread_id": {
            "type": "string"
          },
          "provider_message_id": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "draft_id",
          "thread_id",
          "provider_message_id"
        ],
        "additionalProperties": false
      },
      "PendingApproval": {
        "type": "object",
        "properties": {
          "draft_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "const": "pending_approval"
          }
        },
        "required": [
          "draft_id",
          "status"
        ],
        "additionalProperties": false
      },
      "MessageListItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "direction": {
            "type": "string",
            "enum": [
              "in",
              "out"
            ]
          },
          "from_addr": {
            "type": "string"
          },
          "to_addr": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "comprehension": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string"
                  },
                  "classification": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "direction",
          "from_addr",
          "to_addr",
          "subject",
          "created_at"
        ],
        "additionalProperties": false
      },
      "MessageDetail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "mailbox_id": {
            "type": "string"
          },
          "direction": {
            "type": "string",
            "enum": [
              "in",
              "out"
            ]
          },
          "provider_message_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "rfc_message_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "thread_id": {
            "type": "string"
          },
          "in_reply_to": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "from_addr": {
            "type": "string"
          },
          "to_addr": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "body_raw": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "body_clean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "truncated": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          },
          "comprehension": {
            "anyOf": [
              {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {}
              },
              {
                "type": "null"
              }
            ]
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "object",
              "propertyNames": {
                "type": "string"
              },
              "additionalProperties": {}
            }
          },
          "auth_results": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "spf": {
                    "type": "string",
                    "enum": [
                      "pass",
                      "fail",
                      "softfail",
                      "neutral",
                      "none",
                      "temperror",
                      "permerror"
                    ]
                  },
                  "dkim": {
                    "type": "string",
                    "enum": [
                      "pass",
                      "fail",
                      "softfail",
                      "neutral",
                      "none",
                      "temperror",
                      "permerror"
                    ]
                  },
                  "dmarc": {
                    "type": "string",
                    "enum": [
                      "pass",
                      "fail",
                      "softfail",
                      "neutral",
                      "none",
                      "temperror",
                      "permerror"
                    ]
                  }
                },
                "required": [
                  "spf",
                  "dkim",
                  "dmarc"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "SPF/DKIM/DMARC verdicts from the inbound Authentication-Results header; null if none was forwarded."
          },
          "spam_risk": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "low",
                  "high",
                  "error"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "The layered spam verdict: 'high' from either the free SES x-ses-spam-verdict gate or the Haiku classifier reaching the same conclusion on SES-pass mail; 'low' cleared both; 'error' means the classifier failed and the message proceeded un-quarantined (availability over false quarantine). null when spam scoring never ran for this message."
          },
          "virus_risk": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "low",
                  "high"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "The SES virus verdict from the free x-ses-virus-verdict gate: 'high' means SES flagged the message as malware — it is stored but never delivered (no deliver-toggle exists for malware); 'low' means SES cleared it; null when no verdict was forwarded."
          }
        },
        "required": [
          "id",
          "mailbox_id",
          "direction",
          "thread_id",
          "from_addr",
          "to_addr",
          "subject",
          "created_at",
          "auth_results",
          "spam_risk",
          "virus_risk"
        ],
        "additionalProperties": false
      },
      "Draft": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "mailbox_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "pending_approval",
              "sending",
              "sent",
              "rejected"
            ]
          },
          "to": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "subject": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "reply_to_message_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "requires_human": {
            "type": "boolean"
          },
          "thread_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "mailbox_id",
          "status",
          "subject",
          "text",
          "requires_human",
          "thread_id",
          "created_at",
          "updated_at"
        ],
        "additionalProperties": false
      },
      "Domain": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "created_at"
        ],
        "additionalProperties": false
      },
      "DomainCreated": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "verified",
              "failed"
            ]
          },
          "records": {
            "type": "array",
            "items": {
              "type": "object",
              "propertyNames": {
                "type": "string"
              },
              "additionalProperties": {}
            },
            "description": "Provider DNS records to add for verification."
          }
        },
        "required": [
          "id",
          "name",
          "status",
          "records"
        ],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "KeyScopeError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "const": "key_scope"
          }
        },
        "required": [
          "error",
          "code"
        ],
        "additionalProperties": false
      },
      "SendBlockedByListError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "const": "send_blocked_by_list"
          },
          "reason": {
            "type": "string",
            "enum": [
              "block_match",
              "no_allow_match"
            ]
          },
          "scope": {
            "type": "string",
            "enum": [
              "account",
              "mailbox"
            ]
          },
          "list_entry_id": {
            "description": "The matched block entry (present only on `block_match`).",
            "type": "string"
          }
        },
        "required": [
          "code",
          "reason",
          "scope"
        ],
        "additionalProperties": false
      },
      "IdempotencyConflictError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "const": "idempotency_conflict"
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "error"
        ],
        "additionalProperties": false
      },
      "IdempotencyInProgressError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "const": "idempotency_in_progress"
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "error"
        ],
        "additionalProperties": false
      },
      "ApprovalConflictError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "const": "approval_conflict"
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "error"
        ],
        "additionalProperties": false
      },
      "DeliveryError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "retryable": {
            "type": "boolean"
          },
          "code": {
            "description": "Present only on an ambiguous provider outcome.",
            "type": "string",
            "const": "delivery_outcome_unknown"
          }
        },
        "required": [
          "error",
          "retryable"
        ],
        "additionalProperties": false
      }
    }
  }
}
