{"openapi":"3.1.0","info":{"title":"SuperMailOS API","version":"1.1.0","description":"The SuperMailOS API lets your code and AI agents read, search, organize and send\nbusiness email from your workspace's real mailboxes — the same mail, rules and\nguardrails as the web app.\n\n## Authentication\nCreate a key in **Settings → Developers → API keys** (workspace admins). Keys look\nlike `smk_…`, are shown once, and are sent as `Authorization: Bearer <key>`.\nPrefer calling from a server; never ship a key in public client code.\n\nA key acts for the person who created it and reaches exactly the mailboxes they\ncan open in the app: owners and admins reach every mailbox in the workspace; a\nmember reaches their own mailboxes plus mailboxes shared with them (view-only,\nview-and-send, or full access). Anything else — another workspace, a teammate's\nunshared mailbox — is reported as `404`, never as forbidden. Access follows the\nperson's current role, and a key stops working (`401`) once its creator leaves\nthe workspace.\n\n## Scopes\n| Scope | Allows |\n|---|---|\n| `read` | mailboxes, threads, messages, attachments, search |\n| `send` | `POST /send`, `POST /threads/{id}/reply` |\n| `write` | `PATCH /threads/{id}` (read/unread, star, move, archive, labels), `POST /threads/{id}/draft` — never sends |\n\nA request without the needed scope gets `403` with code `missing_scope`.\n\n## Rate limits\n120 requests per minute per key and 60 per minute per IP, then a\none-minute cooldown. Responses carry `X-RateLimit-Limit` / `X-RateLimit-Remaining`;\na `429` carries `Retry-After` (seconds). Sending has its own per-mailbox and\nper-workspace hourly limits and new-domain warm-up caps (also `429`).\n\n## Idempotency\nSend an `Idempotency-Key` header (any 1–255 printable ASCII characters — a UUID\nis ideal) on `POST /send` and `POST /threads/{id}/reply`. Keys are scoped to your\nAPI key and kept for 24 hours:\n- same key + same body → the original response is replayed (same status and\n  JSON, plus `Idempotency-Replayed: true`); nothing is sent again;\n- same key + a different body → `422` `idempotency_key_reused`;\n- same key while the first request is still running → `409` `idempotency_in_progress`.\nOnly successful responses are stored: a refused request sent nothing, so you may\nfix it and retry with the same key. Always retry sends with the key you first used.\n\n## Errors\nErrors are JSON: `{ \"error\": \"<message>\", \"code\": \"<code>\" }`. `error` is for\nhumans and may change; `code` is stable: `bad_request`, `unauthorized`, `missing_scope`, `forbidden`, `not_found`, `conflict`, `idempotency_in_progress`, `idempotency_key_reused`, `payload_too_large`, `unprocessable`, `locked`, `rate_limited`, `insufficient_storage`, `server_error`, `upstream_failed`.\nA `503` `server_error` with `Retry-After` means the service is briefly unavailable:\nretry, and keep the key — only `401` says it is invalid.\n\n## Pagination\nList endpoints return `nextCursor`; pass it back as `?cursor=` for the next page\n(`null` on the last page). `limit` is 1–100 (default 25).\n\n## Privacy\nBcc recipients appear only to the person who sent the message or was themselves\nBcc'd — the same rule as the app. Reading a thread over the API never marks it\nread; `PATCH` it to change state.\n\n## Ids\nThread, message and attachment ids are opaque strings. A message's `id` is the\nsame value webhooks send as `emailId`; `messageId` is the RFC 5322 Message-ID.\n\n## MCP\nThe same operations are available to AI agents as a Model Context Protocol\nserver (Streamable HTTP) at `https://supermailos.com/api/mcp`, authenticated with the same keys.","contact":{"name":"SuperMailOS","url":"https://supermailos.com/contact"}},"servers":[{"url":"https://supermailos.com","description":"Production"}],"externalDocs":{"description":"Quick reference (agent skill)","url":"https://supermailos.com/.well-known/agent-skills/supermailos/SKILL.md"},"security":[{"bearerAuth":[]}],"tags":[{"name":"Mailboxes"},{"name":"Threads"},{"name":"Messages"},{"name":"Attachments"},{"name":"Sending"}],"paths":{"/api/v1/mailboxes":{"get":{"operationId":"listMailboxes","tags":["Mailboxes"],"summary":"List mailboxes","description":"The mailboxes this key can read, their aliases, what the key may do on each, and unread counts.","responses":{"200":{"description":"Mailboxes.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"application/json":{"schema":{"type":"object","required":["mailboxes"],"properties":{"mailboxes":{"type":"array","items":{"$ref":"#/components/schemas/Mailbox"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"read","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl \"https://supermailos.com/api/v1/mailboxes\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\""},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/mailboxes\", {\n  method: \"GET\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n  },\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.get(\n    \"https://supermailos.com/api/v1/mailboxes\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]}},"/api/v1/threads":{"get":{"operationId":"listThreads","tags":["Threads"],"summary":"List threads","description":"Conversations across the mailboxes this key can read, newest first. Never marks anything read.","parameters":[{"$ref":"#/components/parameters/Mailbox"},{"$ref":"#/components/parameters/Folder"},{"name":"unread","in":"query","schema":{"type":"boolean"},"description":"`true` → only unread conversations."},{"name":"label","in":"query","schema":{"type":"string"}},{"name":"hasAttachments","in":"query","schema":{"type":"boolean"}},{"name":"q","in":"query","schema":{"type":"string","maxLength":500},"description":"Search query (see `/search`). With `q` and no `folder`, every folder but trash and spam is searched."},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"A page of threads.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadList"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"read","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl \"https://supermailos.com/api/v1/threads?folder=inbox&unread=true&limit=25\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\""},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/threads?folder=inbox&unread=true&limit=25\", {\n  method: \"GET\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n  },\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.get(\n    \"https://supermailos.com/api/v1/threads\",\n    params={\n        \"folder\": \"inbox\",\n        \"unread\": \"true\",\n        \"limit\": \"25\",\n    },\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]}},"/api/v1/threads/{id}":{"get":{"operationId":"getThread","tags":["Threads"],"summary":"Get a thread","description":"One conversation with every message, oldest first. Does not mark it read.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Thread id."},{"$ref":"#/components/parameters/Html"}],"responses":{"200":{"description":"The thread.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadDetail"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"read","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl \"https://supermailos.com/api/v1/threads/THREAD_ID\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\""},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/threads/THREAD_ID\", {\n  method: \"GET\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n  },\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.get(\n    \"https://supermailos.com/api/v1/threads/THREAD_ID\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]},"patch":{"operationId":"updateThread","tags":["Threads"],"summary":"Update a thread","description":"Mark read/unread (needs read access), star, move (inbox, archive, trash, spam) or relabel (need manage access: the mailbox's owner, an admin, or a full-access share). Returns the updated thread.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Thread id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"application/json":{"schema":{"type":"object","required":["thread"],"properties":{"thread":{"$ref":"#/components/schemas/Thread"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"write","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X PATCH \"https://supermailos.com/api/v1/threads/THREAD_ID\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"unread\":false,\"folder\":\"archive\",\"addLabels\":[\"Invoices\"]}'"},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/threads/THREAD_ID\", {\n  method: \"PATCH\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"unread\": false,\n    \"folder\": \"archive\",\n    \"addLabels\": [\n      \"Invoices\"\n    ]\n  }),\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.patch(\n    \"https://supermailos.com/api/v1/threads/THREAD_ID\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    json={\n        \"unread\": False,\n        \"folder\": \"archive\",\n        \"addLabels\": [\"Invoices\"],\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]}},"/api/v1/threads/{id}/reply":{"post":{"operationId":"replyToThread","tags":["Sending"],"summary":"Reply to a thread","description":"Reply or reply-all, threaded with In-Reply-To/References, through the same send pipeline as the app (verified domain, suppression list, rate limits, warm-up, storage quota). Supports Idempotency-Key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Thread id."},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplyRequest"}}}},"responses":{"202":{"description":"Accepted for delivery (or a replayed earlier response).","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"Idempotency-Replayed":{"$ref":"#/components/headers/Idempotency-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/Unprocessable"},"423":{"$ref":"#/components/responses/Locked"},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"$ref":"#/components/responses/UpstreamFailed"},"507":{"$ref":"#/components/responses/InsufficientStorage"}},"security":[{"bearerAuth":[]}],"x-required-scope":"send","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST \"https://supermailos.com/api/v1/threads/THREAD_ID/reply\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -d '{\"text\":\"Thanks — received, I'\\''ll get back to you today.\",\"replyAll\":false}'"},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/threads/THREAD_ID/reply\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n    // Reuse the same key when retrying this send; never mails twice.\n    \"Idempotency-Key\": crypto.randomUUID(),\n  },\n  body: JSON.stringify({\n    \"text\": \"Thanks — received, I'll get back to you today.\",\n    \"replyAll\": false\n  }),\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os, uuid\nimport requests\n\nres = requests.post(\n    \"https://supermailos.com/api/v1/threads/THREAD_ID/reply\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n        \"Idempotency-Key\": str(uuid.uuid4()),  # reuse it on retries\n    },\n    json={\n        \"text\": \"Thanks — received, I'll get back to you today.\",\n        \"replyAll\": False,\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]}},"/api/v1/threads/{id}/draft":{"post":{"operationId":"draftReply","tags":["Sending"],"summary":"Draft a reply","description":"Save a reply as a draft in the conversation's mailbox for a person to review and send from the app. Nothing is sent.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Thread id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplyRequest"}}}},"responses":{"201":{"description":"Draft saved.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"write","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST \"https://supermailos.com/api/v1/threads/THREAD_ID/draft\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"text\":\"Draft for review: thanks, we can do Thursday at 10.\",\"replyAll\":true}'"},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/threads/THREAD_ID/draft\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    \"text\": \"Draft for review: thanks, we can do Thursday at 10.\",\n    \"replyAll\": true\n  }),\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.post(\n    \"https://supermailos.com/api/v1/threads/THREAD_ID/draft\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    json={\n        \"text\": \"Draft for review: thanks, we can do Thursday at 10.\",\n        \"replyAll\": True,\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]}},"/api/v1/messages":{"get":{"operationId":"listMessages","tags":["Messages"],"summary":"List recent messages","description":"Recent individual messages across the mailboxes this key can read, newest first. For conversations, prefer `GET /threads`.","parameters":[{"name":"mailbox","in":"query","schema":{"type":"string","format":"email"}},{"name":"folder","in":"query","schema":{"type":"string","enum":["inbox","sent","drafts","archive","spam","trash"]}},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"Messages.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"application/json":{"schema":{"type":"object","required":["messages","count"],"properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/MessageSummary"}},"count":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"read","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl \"https://supermailos.com/api/v1/messages?direction=inbound&limit=20\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\""},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/messages?direction=inbound&limit=20\", {\n  method: \"GET\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n  },\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.get(\n    \"https://supermailos.com/api/v1/messages\",\n    params={\n        \"direction\": \"inbound\",\n        \"limit\": \"20\",\n    },\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]}},"/api/v1/messages/{id}":{"get":{"operationId":"getMessage","tags":["Messages"],"summary":"Get a message","description":"One message by id — the `emailId` in webhook payloads.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/Html"}],"responses":{"200":{"description":"The message.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"$ref":"#/components/schemas/Message"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"read","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl \"https://supermailos.com/api/v1/messages/MESSAGE_ID\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\""},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/messages/MESSAGE_ID\", {\n  method: \"GET\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n  },\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.get(\n    \"https://supermailos.com/api/v1/messages/MESSAGE_ID\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]}},"/api/v1/messages/{id}/raw":{"get":{"operationId":"getRawMessage","tags":["Messages"],"summary":"Download a message as .eml","description":"The message as an RFC 5322 file, rebuilt from the stored headers, bodies and attachments. Not byte-identical to the original (transport headers and signatures are not kept).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The .eml file.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"message/rfc822":{"schema":{"type":"string"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"read","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl \"https://supermailos.com/api/v1/messages/MESSAGE_ID/raw\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\" \\\n  -o message.eml"},{"lang":"TypeScript","label":"TypeScript","source":"import { writeFile } from \"node:fs/promises\";\n\nconst res = await fetch(\"https://supermailos.com/api/v1/messages/MESSAGE_ID/raw\", {\n  method: \"GET\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n  },\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nawait writeFile(\"message.eml\", Buffer.from(await res.arrayBuffer()));"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.get(\n    \"https://supermailos.com/api/v1/messages/MESSAGE_ID/raw\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    timeout=30,\n)\nres.raise_for_status()\nwith open(\"message.eml\", \"wb\") as f:\n    f.write(res.content)"}]}},"/api/v1/attachments/{id}":{"get":{"operationId":"getAttachment","tags":["Attachments"],"summary":"Download an attachment","description":"The attachment's bytes with its content type, served as a download.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The file.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"read","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl \"https://supermailos.com/api/v1/attachments/ATTACHMENT_ID\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\" \\\n  -o attachment.bin"},{"lang":"TypeScript","label":"TypeScript","source":"import { writeFile } from \"node:fs/promises\";\n\nconst res = await fetch(\"https://supermailos.com/api/v1/attachments/ATTACHMENT_ID\", {\n  method: \"GET\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n  },\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nawait writeFile(\"attachment.bin\", Buffer.from(await res.arrayBuffer()));"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.get(\n    \"https://supermailos.com/api/v1/attachments/ATTACHMENT_ID\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    timeout=30,\n)\nres.raise_for_status()\nwith open(\"attachment.bin\", \"wb\") as f:\n    f.write(res.content)"}]}},"/api/v1/search":{"get":{"operationId":"searchMail","tags":["Threads"],"summary":"Search mail","description":"Full-text search with operators: `from:`, `to:`, `subject:`, `label:`, `has:attachment`, `is:unread`, `is:starred`, `before:YYYY-MM-DD`, `after:YYYY-MM-DD`, quoted phrases. Searches every folder except trash and spam unless `folder` is given.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","maxLength":500}},{"$ref":"#/components/parameters/Mailbox"},{"$ref":"#/components/parameters/Folder"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"description":"Matching threads.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadList"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}],"x-required-scope":"read","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl \"https://supermailos.com/api/v1/search?q=from%3Abilling+has%3Aattachment+after%3A2026-01-01&limit=10\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\""},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/search?q=from%3Abilling+has%3Aattachment+after%3A2026-01-01&limit=10\", {\n  method: \"GET\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n  },\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os\nimport requests\n\nres = requests.get(\n    \"https://supermailos.com/api/v1/search\",\n    params={\n        \"q\": \"from:billing has:attachment after:2026-01-01\",\n        \"limit\": \"10\",\n    },\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]}},"/api/v1/send":{"post":{"operationId":"sendEmail","tags":["Sending"],"summary":"Send an email","description":"Send a new message as one of your mailboxes. Every guardrail of the app applies: verified domain, suppression list, per-mailbox/workspace hourly limits, new-domain warm-up, storage quota. Supports Idempotency-Key.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendRequest"}}}},"responses":{"202":{"description":"Accepted for delivery (or a replayed earlier response).","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"Idempotency-Replayed":{"$ref":"#/components/headers/Idempotency-Replayed"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"413":{"$ref":"#/components/responses/PayloadTooLarge"},"422":{"$ref":"#/components/responses/Unprocessable"},"423":{"$ref":"#/components/responses/Locked"},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"$ref":"#/components/responses/UpstreamFailed"},"507":{"$ref":"#/components/responses/InsufficientStorage"}},"security":[{"bearerAuth":[]}],"x-required-scope":"send","x-codeSamples":[{"lang":"curl","label":"curl","source":"curl -X POST \"https://supermailos.com/api/v1/send\" \\\n  -H \"Authorization: Bearer $SUPERMAILOS_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -d '{\"from\":\"you@acme.com\",\"to\":\"client@example.com\",\"subject\":\"Your invoice\",\"text\":\"Hi — your invoice is attached in the portal. Thanks!\"}'"},{"lang":"TypeScript","label":"TypeScript","source":"const res = await fetch(\"https://supermailos.com/api/v1/send\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.SUPERMAILOS_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n    // Reuse the same key when retrying this send; never mails twice.\n    \"Idempotency-Key\": crypto.randomUUID(),\n  },\n  body: JSON.stringify({\n    \"from\": \"you@acme.com\",\n    \"to\": \"client@example.com\",\n    \"subject\": \"Your invoice\",\n    \"text\": \"Hi — your invoice is attached in the portal. Thanks!\"\n  }),\n});\nif (!res.ok) throw new Error(`${res.status}: ${(await res.json()).error}`);\nconst data = await res.json();"},{"lang":"Python","label":"Python","source":"import os, uuid\nimport requests\n\nres = requests.post(\n    \"https://supermailos.com/api/v1/send\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['SUPERMAILOS_API_KEY']}\",\n        \"Idempotency-Key\": str(uuid.uuid4()),  # reuse it on retries\n    },\n    json={\n        \"from\": \"you@acme.com\",\n        \"to\": \"client@example.com\",\n        \"subject\": \"Your invoice\",\n        \"text\": \"Hi — your invoice is attached in the portal. Thanks!\",\n    },\n    timeout=30,\n)\nres.raise_for_status()\ndata = res.json()"}]}}},"webhooks":{"message.inbound":{"post":{"summary":"New mail arrived","description":"Sent to your endpoint for `message.inbound`. Respond with a 2xx within 10 seconds; timeouts and non-2xx responses are retried on a backoff (7 attempts in total over about 21 hours). Redirects are not followed.","parameters":[{"name":"X-SuperMail-Event","in":"header","required":true,"schema":{"type":"string","const":"message.inbound"}},{"name":"X-SuperMail-Delivery","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-SuperMail-Timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds."},{"name":"X-SuperMail-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"`t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>`"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"event":{"const":"message.inbound"},"data":{"$ref":"#/components/schemas/InboundEventData"}}}]}}}},"responses":{"200":{"description":"Acknowledged."}}}},"message.outbound":{"post":{"summary":"Mail was sent","description":"Sent to your endpoint for `message.outbound`. Respond with a 2xx within 10 seconds; timeouts and non-2xx responses are retried on a backoff (7 attempts in total over about 21 hours). Redirects are not followed.","parameters":[{"name":"X-SuperMail-Event","in":"header","required":true,"schema":{"type":"string","const":"message.outbound"}},{"name":"X-SuperMail-Delivery","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-SuperMail-Timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds."},{"name":"X-SuperMail-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"`t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>`"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"event":{"const":"message.outbound"},"data":{"$ref":"#/components/schemas/OutboundEventData"}}}]}}}},"responses":{"200":{"description":"Acknowledged."}}}},"message.delivered":{"post":{"summary":"Mail was delivered","description":"Sent to your endpoint for `message.delivered`. Respond with a 2xx within 10 seconds; timeouts and non-2xx responses are retried on a backoff (7 attempts in total over about 21 hours). Redirects are not followed.","parameters":[{"name":"X-SuperMail-Event","in":"header","required":true,"schema":{"type":"string","const":"message.delivered"}},{"name":"X-SuperMail-Delivery","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-SuperMail-Timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds."},{"name":"X-SuperMail-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"`t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>`"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"event":{"const":"message.delivered"},"data":{"$ref":"#/components/schemas/DeliveredEventData"}}}]}}}},"responses":{"200":{"description":"Acknowledged."}}}},"message.bounced":{"post":{"summary":"A recipient bounced","description":"Sent to your endpoint for `message.bounced`. Respond with a 2xx within 10 seconds; timeouts and non-2xx responses are retried on a backoff (7 attempts in total over about 21 hours). Redirects are not followed.","parameters":[{"name":"X-SuperMail-Event","in":"header","required":true,"schema":{"type":"string","const":"message.bounced"}},{"name":"X-SuperMail-Delivery","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-SuperMail-Timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds."},{"name":"X-SuperMail-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"`t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>`"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"event":{"const":"message.bounced"},"data":{"$ref":"#/components/schemas/BouncedEventData"}}}]}}}},"responses":{"200":{"description":"Acknowledged."}}}},"message.complaint":{"post":{"summary":"A recipient complained","description":"Sent to your endpoint for `message.complaint`. Respond with a 2xx within 10 seconds; timeouts and non-2xx responses are retried on a backoff (7 attempts in total over about 21 hours). Redirects are not followed.","parameters":[{"name":"X-SuperMail-Event","in":"header","required":true,"schema":{"type":"string","const":"message.complaint"}},{"name":"X-SuperMail-Delivery","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-SuperMail-Timestamp","in":"header","required":true,"schema":{"type":"string"},"description":"Unix seconds."},{"name":"X-SuperMail-Signature","in":"header","required":true,"schema":{"type":"string"},"description":"`t=<unix>,v1=<hex HMAC-SHA256(secret, \"<t>.<raw body>\")>`"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEnvelope"},{"type":"object","properties":{"event":{"const":"message.complaint"},"data":{"$ref":"#/components/schemas/ComplaintEventData"}}}]}}}},"responses":{"200":{"description":"Acknowledged."}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"smk_…","description":"A workspace API key from Settings → Developers → API keys."}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current minute.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"Idempotency-Replayed":{"description":"`true` when this is a stored response replayed for a repeated Idempotency-Key.","schema":{"type":"string"}}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":1,"maxLength":255},"description":"Makes the request safe to retry for 24 hours (see Idempotency)."},"Mailbox":{"name":"mailbox","in":"query","schema":{"type":"string"},"description":"Mailbox id, address, or alias address."},"Folder":{"name":"folder","in":"query","schema":{"type":"string","enum":["inbox","sent","drafts","archive","spam","trash","starred","snoozed","all"]},"description":"Default `inbox` (`all` = everything but trash and spam)."},"Cursor":{"name":"cursor","in":"query","schema":{"type":"string"},"description":"`nextCursor` from the previous page."},"Limit":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},"Html":{"name":"html","in":"query","schema":{"type":"boolean","default":true},"description":"`false` omits HTML bodies (smaller responses)."}},"responses":{"BadRequest":{"description":"The request is malformed.","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Missing, invalid or revoked API key.","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"The key lacks the scope (`missing_scope`) or the access (`forbidden`).","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Not found — or not reachable with this key.","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"A request with this Idempotency-Key is still in progress.","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PayloadTooLarge":{"description":"Body over 1 MB.","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unprocessable":{"description":"Valid JSON the server can't act on (e.g. unverified domain, suppressed recipient, reused Idempotency-Key).","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Locked":{"description":"Sending is paused for this mailbox or workspace.","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Too many requests.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UpstreamFailed":{"description":"The mail server didn't accept the message; nothing was sent. Safe to retry.","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InsufficientStorage":{"description":"The mailbox is out of storage.","headers":{},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable message."},"code":{"type":"string","description":"Stable machine-readable code.","enum":["bad_request","unauthorized","missing_scope","forbidden","not_found","conflict","idempotency_in_progress","idempotency_key_reused","payload_too_large","unprocessable","locked","rate_limited","insufficient_storage","server_error","upstream_failed"]}}},"EmailAddress":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"},"name":{"type":"string"}}},"Mailbox":{"type":"object","required":["id","address","displayName","aliases","source","access","unread"],"properties":{"id":{"type":"string"},"address":{"type":"string","format":"email"},"displayName":{"type":"string"},"aliases":{"type":"array","items":{"type":"string","format":"email"},"description":"Aliases that deliver into this mailbox. Replies may be sent from an alias."},"source":{"type":"string","enum":["owner","admin","grant"],"description":"How the key reaches it: the key user's own mailbox, as a workspace admin, or shared with them."},"access":{"type":"object","required":["read","send","manage"],"properties":{"read":{"type":"boolean"},"send":{"type":"boolean"},"manage":{"type":"boolean","description":"Move, star, label (needed for most PATCH fields)."}}},"unread":{"type":"integer","description":"Unread conversations in the inbox."}}},"Thread":{"type":"object","required":["id","mailboxId","mailbox","receivedOn","subject","snippet","from","participants","folder","unread","starred","labels","lastMessageAt","hasAttachments","messageCount"],"properties":{"id":{"type":"string"},"mailboxId":{"type":"string"},"mailbox":{"type":"string","format":"email","description":"The mailbox's address."},"receivedOn":{"type":"string","format":"email","description":"Where the conversation arrived (an alias, if so) or the address it was sent from."},"subject":{"type":"string"},"snippet":{"type":"string"},"from":{"$ref":"#/components/schemas/EmailAddress","description":"The other party: latest inbound sender, else the first recipient of the latest sent message."},"participants":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"},"description":"From/To/Cc of every message — never Bcc."},"folder":{"type":"string","enum":["inbox","sent","drafts","archive","spam","trash"]},"unread":{"type":"boolean"},"starred":{"type":"boolean"},"labels":{"type":"array","items":{"type":"string"}},"lastMessageAt":{"type":"string","format":"date-time"},"snoozedUntil":{"type":"string","format":"date-time"},"hasAttachments":{"type":"boolean"},"messageCount":{"type":"integer"}}},"ThreadList":{"type":"object","required":["threads","nextCursor","unread"],"properties":{"threads":{"type":"array","items":{"$ref":"#/components/schemas/Thread"}},"nextCursor":{"type":["string","null"],"description":"Pass as `cursor` for the next page."},"unread":{"type":"integer","description":"Unread conversations matching the filters (all pages)."}}},"Attachment":{"type":"object","required":["id","filename","contentType","size","inline","url"],"properties":{"id":{"type":"string"},"filename":{"type":"string"},"contentType":{"type":"string"},"size":{"type":"integer","description":"Bytes."},"inline":{"type":"boolean","description":"Embedded in the HTML body via `cid:` rather than attached as a file."},"contentId":{"type":"string","description":"Matches `cid:` references in the HTML body."},"url":{"type":"string","description":"Download path (`GET`, same bearer key)."}}},"Message":{"type":"object","required":["id","threadId","mailboxId","direction","from","to","cc","subject","date","read","text","attachments"],"properties":{"id":{"type":"string","description":"Internal message id (webhooks: `emailId`)."},"threadId":{"type":"string"},"mailboxId":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"messageId":{"type":"string","description":"RFC 5322 Message-ID header, e.g. `<abc@acme.com>`."},"from":{"$ref":"#/components/schemas/EmailAddress"},"to":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"}},"cc":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"}},"bcc":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"},"description":"Present only when the key's user sent the message or was Bcc'd on it."},"subject":{"type":"string"},"date":{"type":"string","format":"date-time"},"read":{"type":"boolean"},"text":{"type":"string","description":"Plain-text body."},"html":{"type":"string","description":"HTML body with scripts and event handlers removed (omitted with `?html=false`)."},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}},"auth":{"type":"object","description":"Inbound SPF / DKIM / DMARC verdicts.","properties":{"spf":{"type":"string"},"dkim":{"type":"string"},"dmarc":{"type":"string"}}},"deliveredAt":{"type":"string","format":"date-time","description":"When the recipient's server accepted an outbound message."}}},"ThreadDetail":{"type":"object","required":["thread","messages","permissions"],"properties":{"thread":{"$ref":"#/components/schemas/Thread"},"messages":{"type":"array","items":{"$ref":"#/components/schemas/Message"},"description":"Oldest first."},"permissions":{"type":"object","required":["send","manage"],"properties":{"send":{"type":"boolean"},"manage":{"type":"boolean"}}}}},"ThreadPatch":{"type":"object","additionalProperties":false,"minProperties":1,"properties":{"unread":{"type":"boolean","description":"Needs read access."},"read":{"type":"boolean","description":"Alias for `!unread`."},"starred":{"type":"boolean"},"folder":{"type":"string","enum":["inbox","archive","trash","spam"],"description":"Move to a system folder. `spam` also trains the mailbox on the sender; `spam` → `inbox` forgives them."},"labels":{"type":"array","items":{"type":"string","maxLength":60},"maxItems":20,"description":"Replace every label."},"addLabels":{"type":"array","items":{"type":"string","maxLength":60}},"removeLabels":{"type":"array","items":{"type":"string"},"description":"Case-insensitive."}}},"SendRequest":{"type":"object","required":["from","to"],"properties":{"from":{"type":"string","format":"email","description":"A mailbox (not an alias) the key can send as."},"to":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Comma-separated string or array of addresses."},"cc":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"bcc":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"subject":{"type":"string"},"text":{"type":"string","description":"Plain-text body. `text` or `html` is required; together at most 1 MB."},"html":{"type":"string","description":"HTML body (scripts, handlers and javascript: URLs are stripped)."},"idempotencyKey":{"type":"string","description":"Alternative to the Idempotency-Key header."}}},"ReplyRequest":{"type":"object","properties":{"text":{"type":"string","description":"`text` or `html` is required."},"html":{"type":"string"},"replyAll":{"type":"boolean","default":false,"description":"Reply to everyone on the last message (To + Cc)."},"from":{"type":"string","format":"email","description":"The conversation's mailbox or one of its aliases. Default: the address the mail arrived on."},"to":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Override the computed recipients."},"cc":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Added to the computed Cc."},"bcc":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"subject":{"type":"string","description":"Default: `Re: <subject>`."},"quote":{"type":"boolean","default":false,"description":"Append the previous message, quoted."},"idempotencyKey":{"type":"string","description":"Alternative to the Idempotency-Key header (/reply only)."}}},"SendResponse":{"type":"object","required":["ok","id","messageId","emailId","threadId","mailboxId","from"],"properties":{"ok":{"type":"boolean","const":true},"id":{"type":"string","description":"RFC Message-ID (kept for compatibility; same as `messageId`)."},"messageId":{"type":"string","description":"RFC 5322 Message-ID of the sent message."},"emailId":{"type":["string","null"],"description":"Internal id of the stored Sent copy."},"threadId":{"type":"string"},"mailboxId":{"type":"string"},"from":{"type":"string","format":"email"}}},"DraftResponse":{"type":"object","required":["ok","draftId","replyToThreadId","from","to","subject"],"properties":{"ok":{"type":"boolean","const":true},"draftId":{"type":"string","description":"The draft conversation's id (folder `drafts`)."},"replyToThreadId":{"type":"string"},"from":{"type":"string"},"to":{"type":"string"},"cc":{"type":["string","null"]},"subject":{"type":"string"}}},"MessageSummary":{"type":"object","description":"A message as returned by the original `GET /messages` list.","required":["id","threadId","mailbox","folder","direction","from","to","subject","snippet","bodyText","date","read"],"properties":{"id":{"type":"string"},"threadId":{"type":"string"},"mailbox":{"type":"string","format":"email"},"folder":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"from":{"$ref":"#/components/schemas/EmailAddress"},"to":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"}},"cc":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"}},"subject":{"type":"string"},"snippet":{"type":"string"},"bodyText":{"type":"string"},"date":{"type":"string","format":"date-time"},"read":{"type":"boolean"},"headerMessageId":{"type":"string","description":"RFC 5322 Message-ID."}}},"WebhookEnvelope":{"type":"object","description":"Every webhook POST body. Verify `X-SuperMail-Signature: t=<unix>,v1=<hex>` where hex = HMAC-SHA256(secret, `<t>.<raw body>`), and reject timestamps more than 5 minutes old.","required":["id","event","createdAt","data"],"properties":{"id":{"type":"string","description":"Delivery id (also `X-SuperMail-Delivery`)."},"event":{"type":"string","enum":["message.inbound","message.outbound","message.delivered","message.bounced","message.complaint"]},"createdAt":{"type":"string","format":"date-time"},"data":{"type":"object"}}},"InboundEventData":{"type":"object","description":"`message.inbound` — metadata only; fetch the body with `GET /messages/{emailId}`.","properties":{"emailId":{"type":"string","description":"Internal message id — `GET /api/v1/messages/{emailId}`."},"threadId":{"type":"string"},"mailboxId":{"type":"string"},"mailbox":{"type":"string","format":"email"},"messageId":{"type":"string","description":"RFC 5322 Message-ID."},"inReplyTo":{"type":["string","null"],"description":"RFC In-Reply-To, when present."},"from":{"$ref":"#/components/schemas/EmailAddress"},"to":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"}},"cc":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"}},"subject":{"type":"string"},"snippet":{"type":"string"},"hasAttachments":{"type":"boolean"},"attachmentCount":{"type":"integer"},"isSpam":{"type":"boolean","description":"Filed to Spam on arrival."},"receivedAt":{"type":"string","format":"date-time"}}},"OutboundEventData":{"type":"object","description":"`message.outbound` — a message was sent (app, mobile, mail client or API).","properties":{"threadId":{"type":"string"},"messageId":{"type":"string","description":"RFC 5322 Message-ID."},"mailbox":{"type":"string","format":"email"},"from":{"$ref":"#/components/schemas/EmailAddress"},"to":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"}},"subject":{"type":"string"}}},"DeliveredEventData":{"type":"object","description":"`message.delivered` — the recipient's server accepted an outbound message.","properties":{"threadId":{"type":"string"},"messageId":{"type":"string"},"mailbox":{"type":"string","format":"email"},"to":{"type":"array","items":{"$ref":"#/components/schemas/EmailAddress"}},"subject":{"type":"string"},"deliveredAt":{"type":"string","format":"date-time"}}},"BouncedEventData":{"type":"object","description":"`message.bounced` — a recipient bounced; hard bounces are suppressed automatically.","properties":{"mailbox":{"type":"string","format":"email"},"recipient":{"type":"string","format":"email"},"hard":{"type":"boolean"},"detail":{"type":"string"}}},"ComplaintEventData":{"type":"object","description":"`message.complaint` — a recipient reported a message as spam; they are suppressed.","properties":{"mailbox":{"type":"string","format":"email"},"recipient":{"type":"string","format":"email"}}}}}}