{
  "openapi": "3.1.0",
  "info": {
    "title": "Lucion Mail API",
    "version": "1",
    "description": "Server-to-server API for reading a personal Lucion Mail mailbox and sending plain-text messages. API keys are personal-account credentials. Organization/shared-mailbox access, attachments, HTML bodies, and scheduled sending are not supported in v1.",
    "termsOfService": "https://lucionmail.com/terms",
    "contact": { "url": "https://lucionmail.com/support" }
  },
  "servers": [{ "url": "https://lucionmail.com", "description": "Production" }],
  "security": [{ "MailApiKey": [] }],
  "tags": [
    { "name": "Messages", "description": "Read mailbox bound to the API key messages or send plain-text mail." }
  ],
  "paths": {
    "/api/v1/mail/messages": {
      "get": {
        "tags": ["Messages"],
        "summary": "List mailbox bound to the API key messages",
        "description": "Requires the mail.read scope. Returns a bounded page. Message text and recipients are sensitive; attachment content is not returned.",
        "parameters": [
          { "name": "folder", "in": "query", "required": false, "schema": { "type": "string", "enum": ["inbox", "sent", "drafts", "archive", "trash"] } },
          { "name": "limit", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } },
          { "name": "offset", "in": "query", "required": false, "schema": { "type": "integer", "minimum": 0, "maximum": 10000, "default": 0 } },
          { "$ref": "#/components/parameters/ApiVersion" }
        ],
        "responses": {
          "200": { "description": "A page of account-owned messages.", "headers": { "Cache-Control": { "$ref": "#/components/headers/NoStore" }, "X-Lucion-API-Version": { "$ref": "#/components/headers/ApiVersion" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MessageList" } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "406": { "$ref": "#/components/responses/UnsupportedVersion" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "503": { "$ref": "#/components/responses/Unavailable" }
        },
        "x-required-scope": "mail.read"
      },
      "post": {
        "tags": ["Messages"],
        "summary": "Send a plain-text message",
        "description": "Requires the mail.send scope and a stable Idempotency-Key. A 202 response means the provider accepted the message for processing, not that final delivery occurred.",
        "parameters": [
          { "name": "Idempotency-Key", "in": "header", "required": true, "schema": { "type": "string", "minLength": 1, "maxLength": 256 } },
          { "$ref": "#/components/parameters/ApiVersion" }
        ],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendMessage" } } } },
        "responses": {
          "202": { "description": "Accepted for provider processing.", "headers": { "Cache-Control": { "$ref": "#/components/headers/NoStore" }, "X-Lucion-API-Version": { "$ref": "#/components/headers/ApiVersion" } }, "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "const": true }, "provider": { "const": "resend" }, "providerMessageId": { "type": "string" }, "accountId": { "type": "string", "format": "uuid" }, "scheduledAt": { "type": ["string", "null"], "format": "date-time" } }, "required": ["ok", "provider", "providerMessageId", "accountId", "scheduledAt"] } } } },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "description": "The requested sender is not owned by this account." },
          "409": { "description": "The idempotency key was already used for different message content." },
          "406": { "$ref": "#/components/responses/UnsupportedVersion" },
          "413": { "description": "Request body exceeds 1 MiB." },
          "415": { "description": "Content-Type must be application/json." },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "description": "Provider request outcome is unknown. Retry with the same Idempotency-Key." },
          "503": { "$ref": "#/components/responses/Unavailable" }
        },
        "x-required-scope": "mail.send"
      }
    }
  },
  "components": {
    "securitySchemes": { "MailApiKey": { "type": "http", "scheme": "bearer", "bearerFormat": "Lucion Mail API key", "description": "Create a key in Settings → API keys. The raw key is shown once. Choose mail.read and/or mail.send only as needed." } },
    "parameters": { "ApiVersion": { "name": "X-Lucion-API-Version", "in": "header", "required": false, "schema": { "type": "string", "enum": ["1"] }, "description": "Optional explicit API version. Other values receive HTTP 406." } },
    "headers": { "NoStore": { "schema": { "type": "string", "const": "no-store" }, "description": "Responses must not be stored by shared caches." }, "ApiVersion": { "schema": { "type": "string", "const": "1" }, "description": "API version that produced the response." } },
    "schemas": {
      "MessageList": { "type": "object", "required": ["ok", "messages"], "properties": { "ok": { "const": true }, "messages": { "type": "array", "items": { "$ref": "#/components/schemas/Message" } } } },
      "Message": { "type": "object", "properties": { "id": { "type": "string", "format": "uuid" }, "folder": { "type": "string", "enum": ["inbox", "sent", "drafts", "archive", "trash"] }, "direction": { "type": "string", "enum": ["inbound", "outbound"] }, "from": { "type": "object", "properties": { "address": { "type": "string" }, "name": { "type": "string" } }, "required": ["address", "name"] }, "to": { "type": "array", "items": { "type": "string" } }, "cc": { "type": "array", "items": { "type": "string" } }, "replyTo": { "type": ["string", "null"] }, "subject": { "type": "string" }, "text": { "type": "string" }, "preview": { "type": "string" }, "attachments": { "type": "array", "items": { "type": "object" }, "description": "Metadata only; attachment file contents are not returned." }, "read": { "type": "boolean" }, "starred": { "type": "boolean" }, "deliveryStatus": { "type": "string" }, "receivedAt": { "type": ["string", "null"], "format": "date-time" }, "sentAt": { "type": ["string", "null"], "format": "date-time" }, "createdAt": { "type": "string", "format": "date-time" } } },
      "SendMessage": { "type": "object", "additionalProperties": false, "required": ["to", "subject", "text"], "properties": { "from": { "type": "string", "description": "Must be an address owned by the Mail account bound to the API key." }, "to": { "$ref": "#/components/schemas/Recipients" }, "cc": { "$ref": "#/components/schemas/Recipients" }, "bcc": { "$ref": "#/components/schemas/Recipients" }, "replyTo": { "type": "string" }, "subject": { "type": "string", "minLength": 1, "maxLength": 200 }, "text": { "type": "string", "maxLength": 500000 }, "priority": { "type": "string", "enum": ["low", "normal", "high"] } } },
      "Recipients": { "oneOf": [{ "type": "string", "description": "Delimited recipient addresses." }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 20 } ] },
      "Error": { "type": "object", "required": ["error"], "properties": { "error": { "type": "string" } } }
    },
    "responses": {
      "BadRequest": { "description": "Invalid request data.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "Unauthorized": { "description": "Missing, invalid, expired, revoked, or insufficient-scope key.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
      "UnsupportedVersion": { "description": "Unsupported requested API version." },
      "RateLimited": { "description": "Rate limit reached. Honor Retry-After and apply bounded backoff." },
      "Unavailable": { "description": "Mail storage, provider, or request-protection dependency unavailable." }
    }
  }
}
