{
  "openapi": "3.1.0",
  "info": {
    "title": "terriblemail API",
    "version": "1.0.0",
    "description": "Programmatic email for scripts and agents. All API operations are tenant-scoped to the Bearer key owner."
  },
  "servers": [{"url": "https://api.terriblemail.com"}],
  "security": [{"bearerAuth": []}],
  "paths": {
    "/healthz": {"get": {"security": [], "operationId": "health", "responses": {"200": {"description": "Healthy"}}}},
    "/readyz": {"get": {"security": [], "operationId": "ready", "responses": {"200": {"description": "Application and database ready"}, "503": {"$ref": "#/components/responses/Error"}}}},
    "/v1/account": {"get": {"operationId": "getAccount", "x-required-scope": "account:read", "responses": {"200": {"description": "Authenticated account", "content": {"application/json": {"schema": {"type": "object"}}}}}}},
    "/v1/usage": {"get": {"operationId": "getUsage", "x-required-scope": "account:read", "responses": {"200": {"description": "Current Stripe billing-period usage and limits for paid accounts, or UTC calendar-month usage for free accounts", "content": {"application/json": {"schema": {"type": "object"}}}}}}},
    "/v1/emails": {
      "post": {
        "operationId": "sendEmail",
        "x-required-scope": "send",
        "summary": "Send an email (delivery and estimated MIME bytes are charged per recipient)",
        "parameters": [{"name": "Idempotency-Key", "in": "header", "required": false, "schema": {"type": "string", "maxLength": 200}}],
        "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendEmailRequest"}}}},
        "responses": {
          "201": {"description": "Sent", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SendEmailResponse"}}}},
          "400": {"$ref": "#/components/responses/Error"}, "401": {"$ref": "#/components/responses/Error"}, "429": {"$ref": "#/components/responses/Error"}, "503": {"$ref": "#/components/responses/Error"}
        }
      }
    },
    "/v1/messages": {"get": {"operationId": "listMessages", "x-required-scope": "messages:read", "responses": {"200": {"description": "Newest 100 messages", "content": {"application/json": {"schema": {"type": "object", "properties": {"data": {"type": "array", "items": {"$ref": "#/components/schemas/Message"}}}}}}}}}},
    "/v1/messages/{id}": {"get": {"operationId": "getMessage", "x-required-scope": "messages:read", "parameters": [{"$ref": "#/components/parameters/ID"}], "responses": {"200": {"description": "Message", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Message"}}}}, "404": {"$ref": "#/components/responses/Error"}}}},
    "/v1/messages/{id}/raw": {"get": {"operationId": "getRawMessage", "x-required-scope": "messages:read", "summary": "Create a five-minute download URL for an inbound raw MIME message", "parameters": [{"$ref": "#/components/parameters/ID"}, {"name": "acknowledge_risk", "in": "query", "required": false, "description": "Set to 1 to access raw content for a quarantined message", "schema": {"type": "string", "const": "1"}}], "responses": {"200": {"description": "Presigned private S3 download URL"}, "409": {"$ref": "#/components/responses/Error"}, "404": {"$ref": "#/components/responses/Error"}}}},
    "/v1/inboxes": {
      "get": {"operationId": "listInboxes", "x-required-scope": "inboxes:read", "responses": {"200": {"description": "Inboxes"}}},
      "post": {"operationId": "createInbox", "x-required-scope": "inboxes:write", "requestBody": {"required": true, "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateInboxRequest"}}}}, "responses": {"201": {"description": "Generated send-and-receive inbox and one-time webhook signing secret"}, "400": {"$ref": "#/components/responses/Error"}, "429": {"$ref": "#/components/responses/Error"}}}
    },
    "/v1/inboxes/{id}": {"delete": {"operationId": "deleteInbox", "x-required-scope": "inboxes:write", "parameters": [{"$ref": "#/components/parameters/ID"}], "responses": {"204": {"description": "Deleted"}, "404": {"$ref": "#/components/responses/Error"}}}},
    "/mcp": {"post": {"operationId": "mcp", "summary": "MCP Streamable HTTP endpoint", "description": "Stateless JSON-RPC 2.0 endpoint implementing MCP protocol version 2025-11-25.", "requestBody": {"required": true, "content": {"application/json": {"schema": {"type": "object"}}}}, "responses": {"200": {"description": "JSON-RPC response"}, "202": {"description": "Notification accepted"}}}}
  },
  "components": {
    "securitySchemes": {"bearerAuth": {"type": "http", "scheme": "bearer", "description": "API key beginning with tm_live_. Keys can be scoped to send, account:read, messages:read, inboxes:read, and inboxes:write; may expire; may restrict recipients; and have a per-minute request ceiling."}},
    "parameters": {"ID": {"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}},
    "responses": {"Error": {"description": "Error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/Error"}}}}},
    "schemas": {
      "SendEmailRequest": {"type": "object", "additionalProperties": false, "required": ["from", "to", "subject"], "anyOf": [{"required": ["text"]}, {"required": ["html"]}], "properties": {"from": {"type": "string", "format": "email", "description": "Enabled inbox address owned by the authenticated account. Replies return to this inbox."}, "to": {"type": "array", "minItems": 1, "maxItems": 50, "items": {"type": "string", "format": "email"}}, "subject": {"type": "string", "maxLength": 998}, "text": {"type": "string"}, "html": {"type": "string"}, "headers": {"type": "object", "description": "Optional X-* headers plus validated List-Unsubscribe and List-Unsubscribe-Post.", "additionalProperties": {"type": "string"}}, "attachments": {"type": "array", "maxItems": 10, "description": "Up to 5 MiB decoded total. Executable formats are rejected.", "items": {"$ref": "#/components/schemas/Attachment"}}}},
      "SendEmailResponse": {"type": "object", "required": ["id", "status", "created_at"], "properties": {"id": {"type": "string"}, "status": {"const": "sent"}, "provider_id": {"type": "string"}, "created_at": {"type": "string", "format": "date-time"}}},
      "CreateInboxRequest": {"type": "object", "additionalProperties": false, "description": "The service generates a globally unique readable address. Every inbox can send and receive.", "properties": {"name": {"type": "string", "maxLength": 80}, "webhook_url": {"type": "string", "format": "uri", "description": "Public HTTPS endpoint"}}},
      "Attachment": {"type": "object", "additionalProperties": false, "required": ["filename", "content_type", "content_base64"], "properties": {"filename": {"type": "string"}, "content_type": {"type": "string"}, "content_base64": {"type": "string", "contentEncoding": "base64"}, "disposition": {"enum": ["attachment", "inline"], "default": "attachment"}, "content_id": {"type": "string"}}},
      "Message": {"type": "object", "required": ["id", "direction", "status", "from", "to", "subject", "size_bytes", "created_at"], "properties": {"id": {"type": "string"}, "direction": {"enum": ["inbound", "outbound"]}, "status": {"type": "string", "description": "Inbound malware failures use quarantined and omit parsed content."}, "provider_id": {"type": "string"}, "inbox_id": {"type": "string"}, "from": {"type": "string"}, "to": {"type": "array", "items": {"type": "string"}}, "subject": {"type": "string"}, "text": {"type": "string"}, "html": {"type": "string"}, "headers": {"type": "object", "additionalProperties": {"type": "string"}}, "attachments": {"type":"array", "items":{"type":"object"}}, "spam_verdict": {"type": "string"}, "virus_verdict": {"type": "string"}, "size_bytes": {"type": "integer", "format": "int64", "minimum": 0}, "created_at": {"type": "string", "format": "date-time"}}},
      "Error": {"type": "object", "required": ["error"], "properties": {"error": {"type": "object", "required": ["code", "message"], "properties": {"code": {"type": "string"}, "message": {"type": "string"}}}}}
    }
  }
}
