{
  "openapi": "3.1.0",
  "info": {
    "title": "ISET.email API",
    "version": "1.0.0",
    "description": "Transactional email and mailbox API. Live surface. Authentication: Bearer isk_<domain key> for /v1 transactional endpoints; MCP agents use mcp_ scoped keys or OAuth 2.1 at /mcp. Every accepted message is ML-DSA-65-signed and carries X-Sovereign-Sig.",
    "x-base-url": "https://iset.email"
  },
  "servers": [{ "url": "https://iset.email" }],
  "paths": {
    "/health": {
      "get": {
        "summary": "Service health",
        "responses": { "200": { "description": "Worker is serving", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "type": "boolean" }, "v": { "type": "integer" } } } } } } }
      }
    },
    "/v1/emails": {
      "post": {
        "summary": "Send an email",
        "description": "Resend-shaped. `from` must be a provisioned address on the key's domain. DKIM-signed, fraud-screened before acceptance; emits EMAIL_ACCEPTED (201) and EMAIL_DELIVERED (202) ISP envelopes.",
        "security": [{ "bearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "type": "object", "required": ["from", "to", "subject"], "properties": { "from": { "type": "string", "format": "email" }, "to": { "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string", "format": "email" } }] }, "subject": { "type": "string" }, "html": { "type": "string" }, "text": { "type": "string" } } } } }
        },
        "responses": {
          "200": { "description": "Accepted for delivery", "content": { "application/json": { "schema": { "type": "object", "properties": { "id": { "type": "string" } } } } } },
          "401": { "description": "Missing or invalid key" },
          "422": { "description": "Validation error — { error: { code, message } }" },
          "429": { "description": "Rate limited — Retry-After set" }
        }
      }
    },
    "/v1/mailboxes": {
      "get": {
        "summary": "List provisioned mailboxes",
        "security": [{ "bearerAuth": [] }],
        "responses": { "200": { "description": "Mailbox list" }, "401": { "description": "Unauthorized" } }
      },
      "post": {
        "summary": "Provision a mailbox",
        "security": [{ "bearerAuth": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["address"], "properties": { "address": { "type": "string", "format": "email" }, "kind": { "type": "string", "enum": ["human", "agent"], "default": "human" } } } } } },
        "responses": { "201": { "description": "Created" }, "402": { "description": "Custom-domain limit reached" }, "409": { "description": "Mailbox exists" } }
      }
    },
    "/v2/export": {
      "get": {
        "summary": "Export the signed-in account's mail (NDJSON stream)",
        "description": "Personal-data egress. First line is a header object; following lines are messages. End-to-end-sealed messages appear as ciphertext, readable only with the owner's key.",
        "responses": { "200": { "description": "application/x-ndjson attachment" }, "401": { "description": "Sign in required" } }
      }
    },
    "/mcp": {
      "post": {
        "summary": "MCP server (Streamable HTTP, JSON-RPC 2.0, stateless)",
        "description": "tools/list is a public catalog; tools/call requires a Bearer mcp_ key (scope read|full) or an OAuth 2.1 token. Unauthenticated calls receive 401 + WWW-Authenticate discovery. E2E-sealed mail is never decrypted for agents.",
        "responses": { "200": { "description": "JSON-RPC response" }, "401": { "description": "Unauthorized — starts OAuth discovery" } }
      }
    }
  },
  "components": {
    "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer" } }
  }
}
