{"openapi":"3.1.0","info":{"title":"TrekMail API","version":"1.0.0","description":"TrekMail public API for managing domains, mailboxes, invites, forwarding, and email messages.\n\n## Authentication\n\nTwo token types:\n- **Ops tokens** (`tm_live_` prefix): For domain, mailbox, and infrastructure management.\n- **Message tokens** (`tm_msg_` prefix): For reading and sending email. Pro\/Agency plans only.\n\n## Rate Limits\n\n| Tier | Limit | Scope |\n|------|-------|-------|\n| Ops API | 60 requests\/min | Per token |\n| Message read | 30 requests\/min | Per token |\n| Message send | 5 requests\/min | Per token |\n| Message send daily | 100\/day | Per mailbox |\n| Destructive (delete confirm) | 10\/day | Per token |\n| Destructive account-wide | 50\/day | Per account |\n| Destructive cooldown | 10 seconds | Between confirms |\n| Migration write | 10 requests\/min | Per token |\n| Migration concurrent | 20 server-wide | Global limit |\n\nWhen rate-limited, the API returns `429` with a `Retry-After` header (seconds).\n\n## Idempotency\n\nAll mutating requests (`POST`, `PUT`) require an `Idempotency-Key` header (max 255 characters). Keys are scoped per token and expire after 24 hours."},"servers":[{"url":"\/api\/v1"}],"security":[{"bearerAuth":[]}],"paths":{"\/domains":{"get":{"operationId":"listDomains","summary":"List domains","tags":["Domains"],"parameters":[{"name":"status","in":"query","schema":{"type":"string"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"per_page","in":"query","schema":{"type":"integer","default":50,"maximum":100}}],"responses":{"200":{"description":"Paginated list of domains","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/Domain"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/domains\/{domain}":{"get":{"operationId":"getDomain","summary":"Get a domain","tags":["Domains"],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Domain details","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Domain"}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/domains\/{domain}\/dns-requirements":{"get":{"operationId":"getDnsRequirements","summary":"Get DNS requirements for a domain","tags":["DNS"],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"DNS requirements and checks","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DnsRequirements"}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/domains\/{domain}\/dns-recheck":{"post":{"operationId":"recheckDns","summary":"Trigger a DNS recheck","tags":["DNS"],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"202":{"description":"DNS check queued","content":{"application\/json":{"schema":{"type":"object","properties":{"check_id":{"type":"integer"},"status":{"type":"string","enum":["queued"]},"created_at":{"type":"string","format":"date-time"}}}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/domains\/{domain}\/spam-metrics":{"get":{"operationId":"getSpamMetrics","summary":"Get daily spam metrics","description":"Returns daily spam protection metrics for a domain, including inbound count, spam caught, spam rejected, and clean emails per day. Zero-filled for days without data.","tags":["Spam Protection"],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"integer"},"description":"Domain ID"},{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"maximum":90,"default":30},"description":"Number of days to look back (default 30, max 90)"}],"responses":{"200":{"description":"Daily spam metrics","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","format":"date"},"inbound":{"type":"integer"},"spam":{"type":"integer"},"rejected":{"type":"integer"},"clean":{"type":"integer"}}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/domains\/{domain}\/spam-metrics\/summary":{"get":{"operationId":"getSpamSummary","summary":"Get spam protection summary","description":"Returns aggregated spam protection stats for a domain over the specified period. Includes total inbound, spam rate, protection status, and top triggered filter rules.","tags":["Spam Protection"],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"integer"},"description":"Domain ID"},{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"maximum":90,"default":30},"description":"Number of days to look back (default 30, max 90)"}],"responses":{"200":{"description":"Spam protection summary","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"period_days":{"type":"integer"},"inbound_total":{"type":"integer"},"clean":{"type":"integer"},"spam_detected":{"type":"integer"},"spam_rejected":{"type":"integer"},"virus_detected":{"type":"integer"},"spam_rate":{"type":"number"},"false_positives_released":{"type":"integer"},"user_reported_spam":{"type":"integer"},"status":{"type":"string","enum":["no_data","excellent","good","moderate","high_spam"]},"top_symbols":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"hits":{"type":"integer"}}}}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/dns-checks\/{check}":{"get":{"operationId":"getDnsCheck","summary":"Get DNS check status","tags":["DNS"],"parameters":[{"name":"check","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"DNS check details","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DnsCheck"}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/mailboxes":{"get":{"operationId":"listMailboxes","summary":"List mailboxes","tags":["Mailboxes"],"parameters":[{"name":"domain_id","in":"query","schema":{"type":"integer"}},{"name":"search","in":"query","schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"per_page","in":"query","schema":{"type":"integer","default":50,"maximum":100}}],"responses":{"200":{"description":"Paginated list of mailboxes","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/Mailbox"}}}}}}}}},"post":{"operationId":"createMailbox","summary":"Create a mailbox","tags":["Mailboxes"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["domain_id","local_part","password_mode"],"properties":{"domain_id":{"type":"integer"},"local_part":{"type":"string","pattern":"^[a-z0-9._-]+$","maxLength":64},"display_name":{"type":"string","maxLength":255},"password_mode":{"type":"string","enum":["generated_one_time"]},"storage_allocation_mb":{"type":"integer","minimum":1,"nullable":true,"description":"Optional dedicated storage allocation in megabytes. Omit (or pass null) for shared account pool. Validated against the live pool minus existing dedicated allocations and pending dedicated invites."}}}}}},"responses":{"201":{"description":"Mailbox created","content":{"application\/json":{"schema":{"allOf":[{"$ref":"#\/components\/schemas\/Mailbox"},{"type":"object","properties":{"one_time_password":{"type":"string"}}}]}}}},"409":{"$ref":"#\/components\/responses\/Conflict"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/mailboxes\/invites":{"post":{"operationId":"createInvite","summary":"Create a mailbox invite","tags":["Invites"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["domain_id","local_part","recipient_email"],"properties":{"domain_id":{"type":"integer"},"local_part":{"type":"string","pattern":"^[a-z0-9._-]+$","maxLength":64},"recipient_email":{"type":"string","format":"email","maxLength":255},"expires_in_hours":{"type":"integer","minimum":1,"maximum":720},"storage_allocation_mb":{"type":"integer","minimum":1,"nullable":true,"description":"Optional dedicated storage allocation in megabytes. Omit for shared account pool. Pending dedicated invites count against the available pool until they are redeemed or expire \u2014 the new mailbox inherits this allocation when the recipient redeems."}}}}}},"responses":{"201":{"description":"Invite created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MailboxInvite"}}}},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/mailboxes\/invites:bulk":{"post":{"operationId":"bulkCreateInvites","summary":"Bulk create mailbox invites","tags":["Invites"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["domain_id","items"],"properties":{"domain_id":{"type":"integer"},"items":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["local_part","recipient_email"],"properties":{"local_part":{"type":"string"},"recipient_email":{"type":"string","format":"email"},"storage_allocation_mb":{"type":"integer","minimum":1,"nullable":true,"description":"Optional dedicated allocation in MB for this recipient. Sum across all items is validated against the available pool; over-budget batches are rejected with 422 storage_pool_exceeded."}}}},"expires_in_hours":{"type":"integer","minimum":1,"maximum":720}}}}}},"responses":{"200":{"description":"All invites created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BulkInviteResult"}}}},"207":{"description":"Partial success","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BulkInviteResult"}}}}}}},"\/mailboxes:bulk":{"post":{"operationId":"bulkCreateMailboxes","summary":"Bulk create mailboxes","description":"Create up to 100 mailboxes in a single request. Each item specifies a domain, local part, and password. Returns per-item results with created\/failed status.","tags":["Mailboxes"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["domain_id","local_part","password"],"properties":{"domain_id":{"type":"integer"},"local_part":{"type":"string","maxLength":64,"pattern":"^[a-z0-9._-]+$"},"password":{"type":"string","minLength":12},"storage_allocation_mb":{"type":"integer","minimum":1,"nullable":true,"description":"Optional dedicated allocation in MB. Sum across all items is validated against the available pool; over-budget batches are rejected with 422 storage_pool_exceeded."}}}}}}}}},"responses":{"200":{"description":"All mailboxes created","content":{"application\/json":{"schema":{"type":"object","properties":{"counts":{"type":"object","properties":{"created":{"type":"integer"},"failed":{"type":"integer"}}},"results":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"status":{"type":"string","enum":["created","failed"]},"mailbox_id":{"type":"integer"},"error":{"type":"string"}}}}}}}}},"207":{"description":"Partial success \u2014 some created, some failed"},"422":{"description":"All failed \u2014 validation or business logic error"}}}},"\/mailboxes\/{mailbox}\/enable-imap":{"post":{"operationId":"enableImapAccess","summary":"Enable IMAP access for a mailbox","description":"Enables IMAP access (Message API) for a mailbox by storing an encrypted copy of its password. This is only needed if a Dovecot master user is not configured \u2014 most deployments use master user auth and do not need this endpoint. Requires the current mailbox password for verification.","tags":["Mailboxes"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["password"],"properties":{"password":{"type":"string","description":"Current mailbox password for verification"}}}}}},"responses":{"200":{"description":"IMAP access enabled (or already enabled)","content":{"application\/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["enabled","already_enabled"]},"message":{"type":"string"}}}}}},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/mailboxes\/{mailbox}:delete-intent":{"post":{"operationId":"createDeleteIntent","summary":"Create a delete intent for a mailbox","description":"Initiates a two-step mailbox deletion. Returns risk flags and a confirm URL. The intent expires after the configured TTL (default 10 minutes).","tags":["Delete Intents"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Delete intent created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DeleteIntent"}}}},"404":{"$ref":"#\/components\/responses\/NotFound"},"409":{"$ref":"#\/components\/responses\/Conflict"}}}},"\/delete-intents\/{intent}:confirm":{"post":{"operationId":"confirmDeleteIntent","summary":"Confirm and execute a delete intent","description":"Confirms a pending delete intent. Requires X-Confirm-Delete: true header. Subject to destructive rate limits (10\/token\/day, 50\/account\/day) and 10s cooldown between confirms.","tags":["Delete Intents"],"parameters":[{"name":"intent","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}},{"name":"X-Confirm-Delete","in":"header","required":true,"schema":{"type":"string","enum":["true"]},"description":"Must be set to 'true' to confirm deletion"}],"responses":{"200":{"description":"Delete intent confirmed and executed","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DeleteIntentResult"}}}},"400":{"description":"Missing X-Confirm-Delete header","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"404":{"$ref":"#\/components\/responses\/NotFound"},"409":{"$ref":"#\/components\/responses\/Conflict"},"410":{"$ref":"#\/components\/responses\/Gone"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/mailboxes\/{mailbox}\/forwarding":{"get":{"operationId":"getForwarding","summary":"Get forwarding settings","tags":["Forwarding"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Current forwarding settings","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ForwardingSettings"}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"put":{"operationId":"updateForwarding","summary":"Update forwarding settings","tags":["Forwarding"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["enabled","targets","keep_copy"],"properties":{"enabled":{"type":"boolean"},"targets":{"type":"array","maxItems":1,"items":{"type":"string","format":"email"}},"keep_copy":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated forwarding settings","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ForwardingSettings"}}}},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/mailboxes\/{mailbox}\/aliases":{"get":{"operationId":"listAliases","summary":"List aliases for a mailbox","tags":["Aliases"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Aliases with primary address and limits","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/MailboxAlias"}},"primary":{"type":"object","properties":{"email":{"type":"string"},"domain":{"type":"string"}}},"limits":{"type":"object","properties":{"used":{"type":"integer"},"max":{"type":"integer"}}}}}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"post":{"operationId":"createAlias","summary":"Create an alias for a mailbox","tags":["Aliases"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["local_part","domain_id"],"properties":{"local_part":{"type":"string","maxLength":64,"pattern":"^[a-z0-9._-]+$"},"domain_id":{"type":"integer"},"can_receive":{"type":"boolean","default":true},"can_send":{"type":"boolean","default":false}}}}}},"responses":{"201":{"description":"Alias created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MailboxAlias"}}}},"403":{"$ref":"#\/components\/responses\/Forbidden"},"409":{"description":"Address already in use"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/mailboxes\/{mailbox}\/aliases\/{alias}":{"patch":{"operationId":"updateAlias","summary":"Update an alias","tags":["Aliases"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}},{"name":"alias","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application\/json":{"schema":{"type":"object","properties":{"is_active":{"type":"boolean"},"can_receive":{"type":"boolean"},"can_send":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated alias","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MailboxAlias"}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"delete":{"operationId":"deleteAlias","summary":"Delete an alias","tags":["Aliases"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}},{"name":"alias","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Alias deleted","content":{"application\/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/mailboxes\/{mailbox}\/message-tokens":{"post":{"operationId":"createMessageToken","summary":"Create a mailbox message token","description":"Creates a new message token for the specified mailbox. The plain token is returned only once in the response. Pro\/Agency plans only.","tags":["Message Tokens"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","scopes"],"properties":{"name":{"type":"string","maxLength":255},"scopes":{"type":"array","minItems":1,"items":{"type":"string","enum":["messages:read","messages:send"]}},"expires_in":{"type":"string","enum":["7d","30d","90d","never"],"default":"never"}}}}}},"responses":{"201":{"description":"Message token created. The token value is returned only once.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MessageTokenCreated"}}}},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}},"get":{"operationId":"listMessageTokens","summary":"List message tokens for a mailbox","tags":["Message Tokens"],"parameters":[{"name":"mailbox","in":"path","required":true,"schema":{"type":"integer"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}}],"responses":{"200":{"description":"Paginated list of message tokens","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/MessageToken"}}}}}}},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/message-tokens\/{token}":{"delete":{"operationId":"revokeMessageToken","summary":"Revoke a message token","tags":["Message Tokens"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Token revoked","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MessageToken"}}}},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/messages":{"get":{"operationId":"listMessages","summary":"List messages in a mailbox folder","description":"Returns messages from the authenticated mailbox's IMAP folder, sorted newest-first with cursor-based pagination. Requires a message token with `messages:read` scope.","tags":["Messages"],"security":[{"messageTokenAuth":[]}],"parameters":[{"name":"folder","in":"query","description":"IMAP folder path (default: INBOX)","schema":{"type":"string","default":"INBOX","maxLength":255}},{"name":"limit","in":"query","description":"Max messages to return (1-50)","schema":{"type":"integer","default":20,"minimum":1,"maximum":50}},{"name":"before_uid","in":"query","description":"Cursor: only return messages with UID < this value","schema":{"type":"integer","minimum":1}},{"name":"since","in":"query","description":"Only return messages since this date (ISO 8601)","schema":{"type":"string","format":"date"}},{"name":"unread_only","in":"query","description":"Only return unread messages","schema":{"type":"boolean","default":false}},{"name":"search","in":"query","description":"Filter by subject keyword (max 200 chars)","schema":{"type":"string","maxLength":200}}],"responses":{"200":{"description":"Message list with pagination","content":{"application\/json":{"schema":{"type":"object","properties":{"mailbox":{"type":"string","format":"email"},"folder":{"type":"string"},"messages":{"type":"array","items":{"$ref":"#\/components\/schemas\/MessageSummary"}},"pagination":{"type":"object","properties":{"has_more":{"type":"boolean"},"next_before_uid":{"type":"integer","nullable":true}}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"},"502":{"description":"IMAP connection failed (retryable)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/messages\/{uid}":{"get":{"operationId":"getMessage","summary":"Get a single message by UID","description":"Returns full message details including body and attachment metadata. Requires a message token with `messages:read` scope.","tags":["Messages"],"security":[{"messageTokenAuth":[]}],"parameters":[{"name":"uid","in":"path","required":true,"description":"IMAP UID of the message","schema":{"type":"integer"}},{"name":"folder","in":"query","description":"IMAP folder path (default: INBOX)","schema":{"type":"string","default":"INBOX","maxLength":255}}],"responses":{"200":{"description":"Full message details","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MessageDetail"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"},"502":{"description":"IMAP connection failed (retryable)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}},"patch":{"operationId":"updateMessageFlags","summary":"Update message flags (mark as read\/unread, star\/unstar)","description":"Sets or removes IMAP flags on a message. Use `seen: true` to mark as read, `seen: false` to mark as unread, `flagged: true\/false` to star\/unstar. At least one flag must be specified. Requires a message token with `messages:read` scope. This operation is idempotent \u2014 no Idempotency-Key required.","tags":["Messages"],"security":[{"messageTokenAuth":[]}],"parameters":[{"name":"uid","in":"path","required":true,"description":"IMAP UID of the message","schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["flags"],"properties":{"folder":{"type":"string","default":"INBOX","maxLength":255,"description":"IMAP folder path (default: INBOX)"},"flags":{"type":"object","description":"Flags to set. At least one flag must be specified.","properties":{"seen":{"type":"boolean","description":"Mark as read (true) or unread (false)"},"flagged":{"type":"boolean","description":"Star (true) or unstar (false)"}}}}}}}},"responses":{"200":{"description":"Flags updated successfully","content":{"application\/json":{"schema":{"type":"object","properties":{"uid":{"type":"integer"},"flags":{"type":"array","items":{"type":"string"},"description":"Current IMAP flags after update (e.g. [\"\\\\Seen\", \"\\\\Flagged\"])"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"},"502":{"description":"IMAP connection failed (retryable)","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/messages\/folders":{"get":{"operationId":"listMessageFolders","summary":"List mailbox folders","description":"Returns all IMAP folders for the authenticated mailbox with their hierarchy delimiter and message counts. Nesting is conveyed by `path` split on `delimiter` (e.g. \"Clients\/Acme\/Invoices\" with delimiter \"\/\"). Requires a message token with `messages:read` scope.","tags":["Messages"],"security":[{"messageTokenAuth":[]}],"responses":{"200":{"description":"Folder list","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MessageFolderList"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"},"502":{"description":"Could not connect to the mailbox"}}},"post":{"operationId":"createMessageFolder","summary":"Create a folder","description":"Creates a new IMAP folder. Reserved names (INBOX, Sent, Drafts, Junk, Trash, Archive, Scheduled) are rejected. Pass `parent` (the raw path of an existing folder) to create a nested subfolder \u2014 e.g. parent=\"Projects\" + name=\"2026\" creates \"Projects\/2026\". Requires a message token with `messages:write` scope.","tags":["Messages"],"security":[{"messageTokenAuth":[]}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateMessageFolderRequest"}}}},"responses":{"201":{"description":"Folder created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MessageFolderMutationResponse"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/messages\/folders\/{path}":{"patch":{"operationId":"renameMessageFolder","summary":"Rename a folder","description":"Renames a custom folder (changes the leaf name). Special folders cannot be renamed. Requires a message token with `messages:write` scope.","tags":["Messages"],"security":[{"messageTokenAuth":[]}],"parameters":[{"name":"path","in":"path","required":true,"description":"Raw IMAP path of the folder, URL-encoded (may contain the server's hierarchy delimiter).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RenameMessageFolderRequest"}}}},"responses":{"200":{"description":"Folder renamed","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MessageFolderMutationResponse"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"operationId":"deleteMessageFolder","summary":"Delete a folder","description":"Deletes a custom folder and ALL of its subfolders (the whole subtree). Special folders cannot be deleted. Requires a message token with `messages:write` scope and an `X-Idempotency-Key` header.","tags":["Messages"],"security":[{"messageTokenAuth":[]}],"parameters":[{"name":"path","in":"path","required":true,"description":"Raw IMAP path of the folder, URL-encoded (may contain the server's hierarchy delimiter).","schema":{"type":"string"}},{"name":"X-Idempotency-Key","in":"header","required":true,"description":"Unique idempotency key for this delete request (max 255 chars)","schema":{"type":"string","maxLength":255}}],"responses":{"204":{"description":"Folder deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/messages\/send":{"post":{"operationId":"sendMessage","summary":"Send an email from the mailbox","description":"Queues an email for sending from the authenticated mailbox. Requires a message token with `messages:send` scope. An `X-Idempotency-Key` header is required to prevent duplicate sends.","tags":["Messages"],"security":[{"messageTokenAuth":[]}],"parameters":[{"name":"X-Idempotency-Key","in":"header","required":true,"description":"Unique idempotency key for this send request (max 255 chars)","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SendMessageRequest"}}}},"responses":{"202":{"description":"Message queued for delivery","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SendMessageResponse"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"409":{"$ref":"#\/components\/responses\/Conflict"},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/messages\/_ping":{"get":{"operationId":"pingMessageToken","summary":"Verify message token connectivity","description":"Returns the mailbox address and scopes for the authenticated message token. Use this to verify a token is valid before making other requests.","tags":["Messages"],"security":[{"messageTokenAuth":[]}],"responses":{"200":{"description":"Token is valid","content":{"application\/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"mailbox":{"type":"string","format":"email"},"scopes":{"type":"array","items":{"type":"string","enum":["messages:read","messages:send"]}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/migrations":{"get":{"operationId":"listMigrations","summary":"List email migrations","tags":["Migrations"],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","validating","planning","processing","completed","failed","cancelled"]}},{"name":"mailbox_id","in":"query","schema":{"type":"integer"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"per_page","in":"query","schema":{"type":"integer","default":20,"maximum":100}}],"responses":{"200":{"description":"Paginated list of migrations","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/MigrationJob"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/InsufficientScope"}}},"post":{"operationId":"startMigration","summary":"Start email migration","tags":["Migrations"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["provider","mailbox_id","source_host","source_port","source_security","source_email","source_password"],"properties":{"provider":{"type":"string","enum":["gmail","outlook","yahoo","icloud","generic_imap"]},"mailbox_id":{"type":"integer"},"source_host":{"type":"string"},"source_port":{"type":"integer"},"source_security":{"type":"string","enum":["ssl","tls","none"]},"source_email":{"type":"string","format":"email"},"source_username":{"type":"string","nullable":true},"source_password":{"type":"string"},"selected_folders":{"type":"array","items":{"type":"string"},"nullable":true},"import_since":{"type":"string","format":"date","nullable":true},"skip_duplicates":{"type":"boolean","default":true}}}}}},"responses":{"201":{"description":"Migration started","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/MigrationJob"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/InsufficientScope"},"409":{"$ref":"#\/components\/responses\/Conflict"},"422":{"$ref":"#\/components\/responses\/ValidationError"},"503":{"description":"Server at migration capacity. Retry later.","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/migrations\/test-connection":{"post":{"operationId":"testMigrationConnection","summary":"Test source IMAP connection","tags":["Migrations"],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["source_host","source_port","source_security","source_email","source_password"],"properties":{"source_host":{"type":"string"},"source_port":{"type":"integer"},"source_security":{"type":"string","enum":["ssl","tls","none"]},"source_email":{"type":"string","format":"email"},"source_username":{"type":"string","nullable":true},"source_password":{"type":"string"}}}}}},"responses":{"200":{"description":"Connection successful with folder list","content":{"application\/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"folders":{"type":"object","additionalProperties":{"type":"integer"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/InsufficientScope"},"422":{"description":"Connection failed","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}},"\/migrations\/{job}":{"get":{"operationId":"getMigration","summary":"Get migration details","tags":["Migrations"],"parameters":[{"name":"job","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Migration details with per-folder breakdown","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/MigrationJob"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"delete":{"operationId":"deleteMigration","summary":"Delete a migration record","tags":["Migrations"],"parameters":[{"name":"job","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Migration record deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"},"409":{"$ref":"#\/components\/responses\/Conflict"}}}},"\/migrations\/{job}:cancel":{"post":{"operationId":"cancelMigration","summary":"Cancel a running migration","tags":["Migrations"],"parameters":[{"name":"job","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Migration cancelled","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/MigrationJob"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"},"409":{"$ref":"#\/components\/responses\/Conflict"}}}},"\/migrations\/{job}:retry":{"post":{"operationId":"retryMigration","summary":"Retry a failed or cancelled migration","tags":["Migrations"],"parameters":[{"name":"job","in":"path","required":true,"schema":{"type":"integer"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Migration retried","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/MigrationJob"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"},"409":{"$ref":"#\/components\/responses\/Conflict"}}}},"\/migrations\/bulk\/{batch}":{"delete":{"operationId":"deleteBulkMigration","summary":"Delete a bulk migration batch record","description":"Delete a completed, failed, or cancelled bulk migration batch. Cannot delete active batches.","tags":["Bulk Migrations"],"parameters":[{"name":"batch","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Batch record deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"},"409":{"$ref":"#\/components\/responses\/Conflict"}}}},"\/migrations\/bulk\/{batch}\/jobs\/{job}\/password":{"patch":{"operationId":"updateBulkMigrationJobPassword","summary":"Update source password for a failed bulk migration job","description":"Update the source IMAP password for a failed job within a bulk migration batch. Only works on jobs with 'failed' status.","tags":["Bulk Migrations"],"parameters":[{"name":"batch","in":"path","required":true,"schema":{"type":"integer"}},{"name":"job","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["source_password"],"properties":{"source_password":{"type":"string","maxLength":255,"description":"New source IMAP password or app password"}}}}}},"responses":{"200":{"description":"Password updated"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/drive\/spaces":{"get":{"operationId":"listDriveSpaces","summary":"List Drive spaces the caller can access","tags":["Drive"],"responses":{"200":{"description":"Array of DriveSpace objects (account + mailbox-personal)","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}}},"\/drive\/storage":{"get":{"operationId":"getDriveStorage","summary":"Account-wide Drive pool snapshot (used\/limit\/addon)","tags":["Drive"],"responses":{"200":{"description":"Pool snapshot","content":{"application\/json":{"schema":{"type":"object"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}}},"\/drive\/spaces\/{space}\/usage":{"get":{"operationId":"getDriveSpaceUsage","summary":"Per-space quota usage","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"},"description":"'account' | 'mailbox:N' | numeric DriveSpace id"}],"responses":{"200":{"description":"Quota snapshot for the space"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/drive\/spaces\/{space}\/folders":{"get":{"operationId":"listDriveRootFolders","summary":"List root folders + files in a space","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"dir","in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Folder + file listing with next_cursor"}}},"post":{"operationId":"createDriveFolder","summary":"Create a folder","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255},"parent_id":{"type":"integer","nullable":true},"color":{"type":"string"},"is_shared":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Folder created"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/drive\/spaces\/{space}\/folders\/{folder}":{"get":{"operationId":"showDriveFolder","summary":"List a folder's children + files","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"name":"folder","in":"path","required":true,"schema":{"type":"integer"}},{"name":"sort","in":"query","schema":{"type":"string"}},{"name":"dir","in":"query","schema":{"type":"string","enum":["asc","desc"]}},{"name":"per_page","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Folder contents"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/drive\/spaces\/{space}\/folder-tree":{"get":{"operationId":"getDriveFolderTree","summary":"Full folder hierarchy for a space","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Nested folder tree"}}}},"\/drive\/spaces\/{space}\/all-ids":{"get":{"operationId":"listDriveAllIds","summary":"All folder + file ids in a space (bulk-select helper)","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"folder_ids[] + file_ids[]"}}}},"\/drive\/spaces\/{space}\/folders\/{folder}\/all-ids":{"get":{"operationId":"listDriveAllIdsInFolder","summary":"All ids beneath a specific folder (bulk-select helper)","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"name":"folder","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"folder_ids[] + file_ids[] under the folder"}}}},"\/drive\/spaces\/{space}\/trash":{"get":{"operationId":"listDriveTrash","summary":"List trashed items in a space","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"name":"per_page","in":"query","schema":{"type":"integer","default":50,"maximum":200}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Trashed items with next_cursor"}}},"delete":{"operationId":"emptyDriveTrash","summary":"Permanently purge every trashed item in a space","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"200":{"description":"{purged_files, purged_folders}"}}}},"\/drive\/files\/{file}":{"get":{"operationId":"showDriveFile","summary":"Get file metadata","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"File metadata"},"404":{"$ref":"#\/components\/responses\/NotFound"}}},"patch":{"operationId":"updateDriveFile","summary":"Rename a file","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":255}}}}}},"responses":{"200":{"description":"Updated file"}}},"delete":{"operationId":"trashDriveFile","summary":"Soft-delete (trash) a file","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"204":{"description":"Trashed"}}}},"\/drive\/files\/{file}\/download":{"get":{"operationId":"getDriveFileDownload","summary":"Get a presigned download URL for a file","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"{download_url, expires_at}"}}}},"\/drive\/files\/{file}:move":{"post":{"operationId":"moveDriveFile","summary":"Move a file to another folder","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["target_folder_id"],"properties":{"target_folder_id":{"type":"integer","nullable":true}}}}}},"responses":{"200":{"description":"Moved file"}}}},"\/drive\/files\/{file}:restore":{"post":{"operationId":"restoreDriveFile","summary":"Restore a trashed file","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"200":{"description":"Restored file"}}}},"\/drive\/files\/{file}:purge":{"delete":{"operationId":"purgeDriveFile","summary":"Permanently delete a file (requires drive:*:purge)","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"204":{"description":"Purged"}}}},"\/drive\/files\/{file}\/share-links":{"get":{"operationId":"listDriveShareLinks","summary":"List share links for a file","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Share links"}}},"post":{"operationId":"createDriveShareLink","summary":"Create a public share link for a file","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application\/json":{"schema":{"type":"object","properties":{"expires_at":{"type":"string","format":"date-time","nullable":true},"max_downloads":{"type":"integer","nullable":true}}}}}},"responses":{"201":{"description":"Share link with one-time token"}}}},"\/drive\/share-links\/{link}":{"delete":{"operationId":"revokeDriveShareLink","summary":"Revoke a share link","tags":["Drive"],"parameters":[{"name":"link","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"204":{"description":"Revoked"}}}},"\/drive\/folders\/{folder}":{"patch":{"operationId":"updateDriveFolder","summary":"Rename \/ recolor a folder","tags":["Drive"],"parameters":[{"name":"folder","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":255},"color":{"type":"string","nullable":true}}}}}},"responses":{"200":{"description":"Updated folder"}}},"delete":{"operationId":"trashDriveFolder","summary":"Soft-delete (trash) a folder and its contents","tags":["Drive"],"parameters":[{"name":"folder","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"204":{"description":"Trashed"}}}},"\/drive\/folders\/{folder}:move":{"post":{"operationId":"moveDriveFolder","summary":"Move a folder under a new parent (or to root)","tags":["Drive"],"parameters":[{"name":"folder","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","properties":{"target_parent_id":{"type":"integer","nullable":true}}}}}},"responses":{"200":{"description":"Moved folder"}}}},"\/drive\/folders\/{folder}:restore":{"post":{"operationId":"restoreDriveFolder","summary":"Restore a trashed folder","tags":["Drive"],"parameters":[{"name":"folder","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"200":{"description":"Restored folder"}}}},"\/drive\/folders\/{folder}:share-with-account":{"post":{"operationId":"shareDriveFolderWithAccount","summary":"Promote a folder to a top-level account-shared folder","tags":["Drive"],"parameters":[{"name":"folder","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"200":{"description":"Folder updated with is_shared=true"}}}},"\/drive\/folders\/{folder}:stop-sharing":{"post":{"operationId":"stopSharingDriveFolder","summary":"Stop account-wide sharing for a folder","tags":["Drive"],"parameters":[{"name":"folder","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"200":{"description":"Folder updated with is_shared=false"}}}},"\/drive\/folders\/{folder}:purge":{"delete":{"operationId":"purgeDriveFolder","summary":"Permanently delete a folder + descendants (requires drive:*:purge)","tags":["Drive"],"parameters":[{"name":"folder","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"204":{"description":"Purged"}}}},"\/drive\/spaces\/{space}\/uploads:initiate":{"post":{"operationId":"initiateDriveUpload","summary":"Initiate a single-part or multi-part upload","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["name","size_bytes"],"properties":{"name":{"type":"string","maxLength":255},"size_bytes":{"type":"integer"},"folder_id":{"type":"integer","nullable":true},"mime_type":{"type":"string","nullable":true}}}}}},"responses":{"201":{"description":"Upload session with presigned PUT URL(s)"}}}},"\/drive\/uploads\/{file}:complete":{"post":{"operationId":"completeDriveUpload","summary":"Finalize a multi-part upload (mark file as available)","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["parts"],"properties":{"parts":{"type":"array","items":{"type":"object","properties":{"part_number":{"type":"integer"},"etag":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"File marked available"}}}},"\/drive\/uploads\/{file}:refresh-parts":{"post":{"operationId":"refreshDriveUploadParts","summary":"Re-presign one or more part URLs for an in-flight multipart upload","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["part_numbers"],"properties":{"part_numbers":{"type":"array","items":{"type":"integer"}}}}}}},"responses":{"200":{"description":"Refreshed parts"}}}},"\/drive\/uploads\/{file}:abort":{"post":{"operationId":"abortDriveUpload","summary":"Abort an in-flight upload + release reservation","tags":["Drive"],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Aborted"}}}},"\/drive\/spaces\/{space}\/bulk:trash":{"post":{"operationId":"bulkTrashDrive","summary":"Bulk soft-delete (up to 5000 ids)","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DriveBulkRequest"}}}},"responses":{"200":{"description":"Bulk result counts"}}}},"\/drive\/spaces\/{space}\/bulk:restore":{"post":{"operationId":"bulkRestoreDrive","summary":"Bulk restore from trash (up to 5000 ids)","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DriveBulkRequest"}}}},"responses":{"200":{"description":"Bulk result counts"}}}},"\/drive\/spaces\/{space}\/bulk:move":{"post":{"operationId":"bulkMoveDrive","summary":"Bulk move (up to 5000 ids)","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"allOf":[{"$ref":"#\/components\/schemas\/DriveBulkRequest"},{"type":"object","required":["target_folder_id"],"properties":{"target_folder_id":{"type":"integer","nullable":true}}}]}}}},"responses":{"200":{"description":"Bulk result counts"}}}},"\/drive\/spaces\/{space}\/bulk:purge":{"post":{"operationId":"bulkPurgeDrive","summary":"Bulk permanent delete (up to 5000 ids; requires drive:*:purge)","tags":["Drive"],"parameters":[{"name":"space","in":"path","required":true,"schema":{"type":"string"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DriveBulkRequest"}}}},"responses":{"200":{"description":"Bulk result counts"}}}},"\/drive\/addon":{"get":{"operationId":"getDriveAddon","summary":"Drive Storage Add-on status","tags":["Drive Add-on"],"responses":{"200":{"description":"Add-on state (active\/grace\/inactive + size_gb + period end)"}}}},"\/drive\/addon\/pricing":{"get":{"operationId":"getDriveAddonPricing","summary":"Drive Storage Add-on pricing ladder","tags":["Drive Add-on"],"parameters":[{"name":"currency","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Currency + snap-points + ladder"}}}},"\/drive\/addon\/cancellation-preview":{"get":{"operationId":"getDriveAddonCancellationPreview","summary":"Files at risk if the Drive Add-on is cancelled today","tags":["Drive Add-on"],"responses":{"200":{"description":"Cancellation impact preview"}}}},"\/drive\/devices":{"get":{"operationId":"listDriveDevices","summary":"List Drive sync-device passwords for the account","tags":["Drive Devices"],"description":"Requires `drive:devices:read`. A mailbox-constrained token only sees devices bound to its allowed mailboxes; account-wide devices (mailbox_id=null) are hidden.","responses":{"200":{"description":"Device list (without plaintext or hash)","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/DriveDevice"}}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"}}},"post":{"operationId":"createDriveDevice","summary":"Mint a new Drive sync-device password","tags":["Drive Devices"],"description":"Requires `drive:devices:write`. Returns the plaintext `dsync_\u2026` credential exactly once in `data.password`; it is never recoverable. Rate-limited 20\/hour per account. Per-account cap of 1000 active+revoked rows.","parameters":[{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"type":"object","required":["label","scopes"],"properties":{"label":{"type":"string","minLength":1,"maxLength":64},"scopes":{"type":"array","items":{"type":"string","enum":["drive:account:read","drive:account:write","drive:account:share","drive:account:purge","drive:mailbox:read","drive:mailbox:write","drive:mailbox:share","drive:mailbox:purge"]}},"mailbox_id":{"type":"integer","nullable":true,"description":"Bind to a single mailbox's Drive; omit \/ null = account-wide."},"expires_in_days":{"type":"integer","nullable":true,"minimum":1,"maximum":3650}}}}}},"responses":{"201":{"description":"Device created. `data.password` is the plaintext, returned ONCE.","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"$ref":"#\/components\/schemas\/DriveDevice"},{"type":"object","properties":{"password":{"type":"string","description":"Plaintext dsync_\u2026 credential. Show to user once; never recoverable."}}}]}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/drive\/devices\/{device}":{"delete":{"operationId":"revokeDriveDevice","summary":"Revoke a Drive sync-device password","tags":["Drive Devices"],"description":"Requires `drive:devices:write`. Idempotent \u2014 already-revoked rows return 200 unchanged. Sync clients lose access immediately on the next request.","parameters":[{"name":"device","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"responses":{"200":{"description":"Revoked device","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/DriveDevice"}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/drive\/devices\/{device}:rotate":{"post":{"operationId":"rotateDriveDevice","summary":"Atomic rotate: revoke old + mint new (inherits label\/scopes\/mailbox)","tags":["Drive Devices"],"description":"Requires `drive:devices:write`. New plaintext returned ONCE in `data.password`. Old password stops working immediately. Rate-limited 10\/hour per account.","parameters":[{"name":"device","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#\/components\/parameters\/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application\/json":{"schema":{"type":"object","properties":{"expires_in_days":{"type":"integer","nullable":true,"minimum":1,"maximum":3650,"description":"Override inherited expiry. Omit \/ null = inherit original window."}}}}}},"responses":{"201":{"description":"New device + plaintext","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"$ref":"#\/components\/schemas\/DriveDevice"},{"type":"object","properties":{"password":{"type":"string"},"rotated_from_device_id":{"type":"integer"}}}]}}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API token. Prefix: tm_live_"},"messageTokenAuth":{"type":"http","scheme":"bearer","description":"Mailbox message token. Prefix: tm_msg_. Used for message read\/send operations (TS-2)."}},"schemas":{"MigrationJob":{"type":"object","properties":{"id":{"type":"integer"},"mailbox_id":{"type":"integer"},"mailbox_email":{"type":"string","nullable":true},"provider":{"type":"string","enum":["gmail","outlook","yahoo","icloud","generic_imap"]},"source_host":{"type":"string"},"source_email":{"type":"string","description":"Masked for security"},"status":{"type":"string","enum":["pending","validating","planning","processing","completed","failed","cancelled"]},"progress":{"type":"integer","minimum":0,"maximum":100},"total_messages":{"type":"integer"},"imported_messages":{"type":"integer"},"failed_messages":{"type":"integer"},"skipped_duplicates":{"type":"integer"},"selected_folders":{"type":"array","items":{"type":"string"}},"import_since":{"type":"string","format":"date","nullable":true},"skip_duplicates":{"type":"boolean"},"folders":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string"},"expected":{"type":"integer"},"imported":{"type":"integer"},"failed":{"type":"integer"},"skipped":{"type":"integer"}}}},"error_message":{"type":"string","nullable":true},"poll_hint_seconds":{"type":"integer","nullable":true},"started_at":{"type":"string","format":"date-time","nullable":true},"finished_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"Domain":{"type":"object","properties":{"id":{"type":"integer"},"domain":{"type":"string"},"status":{"type":"string"},"dns_health":{"type":"string","enum":["ok","warn","fail","unknown"]},"last_checked_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"DnsRequirements":{"type":"object","properties":{"required_records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string","nullable":true},"priority":{"type":"integer","nullable":true},"purpose":{"type":"string"}}}},"observed_records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"value":{"type":"string","nullable":true},"priority":{"type":"integer","nullable":true}}}},"checks":{"type":"array","items":{"type":"object","properties":{"check_key":{"type":"string"},"status":{"type":"string","enum":["pass","fail","warn","unknown"]},"details":{"type":"string","nullable":true},"hint":{"type":"string","nullable":true}}}}}},"DnsCheck":{"type":"object","properties":{"id":{"type":"integer"},"domain_id":{"type":"integer"},"status":{"type":"string","enum":["queued","running","succeeded","failed"]},"started_at":{"type":"string","format":"date-time","nullable":true},"completed_at":{"type":"string","format":"date-time","nullable":true},"result":{"type":"object","nullable":true},"error":{"type":"string","nullable":true}}},"Mailbox":{"type":"object","properties":{"id":{"type":"integer"},"email":{"type":"string","format":"email"},"domain_id":{"type":"integer"},"status":{"type":"string"},"display_name":{"type":"string","nullable":true},"forwarding_enabled":{"type":"boolean"},"aliases_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}}},"MailboxInvite":{"type":"object","properties":{"invite_id":{"type":"integer"},"domain_id":{"type":"integer"},"email_to_create":{"type":"string","nullable":true},"recipient_email":{"type":"string","format":"email"},"invite_url":{"type":"string","format":"uri"},"expires_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"BulkInviteResult":{"type":"object","properties":{"batch_id":{"type":"string"},"counts":{"type":"object","properties":{"total":{"type":"integer"},"created":{"type":"integer"},"failed":{"type":"integer"}}},"results":{"type":"array","items":{"type":"object","properties":{"local_part":{"type":"string","nullable":true},"recipient_email":{"type":"string"},"status":{"type":"string","enum":["created","failed"]},"invite_id":{"type":"integer","nullable":true},"error":{"type":"string","nullable":true}}}}}},"DeleteIntent":{"type":"object","properties":{"id":{"type":"integer"},"mailbox_id":{"type":"integer"},"mailbox_email":{"type":"string","format":"email"},"status":{"type":"string","enum":["pending","confirmed","executed","expired","failed"]},"risk_flags":{"type":"array","items":{"type":"string","enum":["has_active_forwarding","has_aliases","has_active_migration"]}},"expires_at":{"type":"string","format":"date-time"},"confirm_url":{"type":"string","format":"uri"},"created_at":{"type":"string","format":"date-time"}}},"DeleteIntentResult":{"type":"object","properties":{"id":{"type":"integer"},"mailbox_id":{"type":"integer"},"mailbox_email":{"type":"string","format":"email"},"status":{"type":"string","enum":["executed"]},"risk_flags":{"type":"array","items":{"type":"string"}},"confirmed_at":{"type":"string","format":"date-time"},"executed_at":{"type":"string","format":"date-time"}}},"MessageTokenCreated":{"type":"object","properties":{"id":{"type":"integer"},"token":{"type":"string","description":"Plain token value. Shown only once."},"prefix":{"type":"string"},"name":{"type":"string"},"mailbox_id":{"type":"integer"},"mailbox_email":{"type":"string","format":"email"},"scopes":{"type":"array","items":{"type":"string","enum":["messages:read","messages:send"]}},"expires_at":{"type":"string","format":"date-time","nullable":true},"reveal":{"type":"string","enum":["one_time"]},"created_at":{"type":"string","format":"date-time"}}},"MessageToken":{"type":"object","properties":{"id":{"type":"integer"},"prefix":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","enum":["messages:read","messages:send"]}},"expires_at":{"type":"string","format":"date-time","nullable":true},"last_used_at":{"type":"string","format":"date-time","nullable":true},"revoked_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"MailboxAlias":{"type":"object","properties":{"id":{"type":"integer"},"email":{"type":"string"},"local_part":{"type":"string"},"domain_id":{"type":"integer"},"domain":{"type":"string"},"type":{"type":"string","enum":["primary","alias"]},"can_receive":{"type":"boolean"},"can_send":{"type":"boolean"},"is_active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ForwardingSettings":{"type":"object","properties":{"enabled":{"type":"boolean"},"targets":{"type":"array","items":{"type":"string","format":"email"}},"keep_copy":{"type":"boolean"},"updated_at":{"type":"string","format":"date-time","nullable":true}}},"EmailAddress":{"type":"object","properties":{"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email"}}},"MessageSummary":{"type":"object","properties":{"uid":{"type":"integer"},"message_id":{"type":"string"},"date":{"type":"string","format":"date-time","nullable":true},"from":{"$ref":"#\/components\/schemas\/EmailAddress"},"to":{"type":"array","items":{"$ref":"#\/components\/schemas\/EmailAddress"}},"subject":{"type":"string"},"flags":{"type":"array","items":{"type":"string"}},"has_attachments":{"type":"boolean"},"preview_text":{"type":"string"}}},"AttachmentMeta":{"type":"object","properties":{"index":{"type":"integer"},"filename":{"type":"string"},"content_type":{"type":"string"},"size_bytes":{"type":"integer"},"disposition":{"type":"string","enum":["attachment","inline"]}}},"MessageDetail":{"allOf":[{"$ref":"#\/components\/schemas\/MessageSummary"},{"type":"object","properties":{"cc":{"type":"array","items":{"$ref":"#\/components\/schemas\/EmailAddress"}},"bcc":{"type":"array","items":{"$ref":"#\/components\/schemas\/EmailAddress"}},"reply_to":{"type":"array","items":{"$ref":"#\/components\/schemas\/EmailAddress"}},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"type":"object","properties":{"text":{"type":"string","nullable":true},"html":{"type":"string","nullable":true}}},"attachments":{"type":"array","items":{"$ref":"#\/components\/schemas\/AttachmentMeta"}}}}]},"MessageFolder":{"type":"object","properties":{"name":{"type":"string","description":"Leaf folder name (modified-UTF7 encoded when it contains non-ASCII)"},"path":{"type":"string","description":"Full IMAP path; split on `delimiter` to reconstruct the hierarchy"},"delimiter":{"type":"string","description":"Hierarchy separator reported by the server (e.g. \"\/\" or \".\")"},"unseen":{"type":"integer","description":"Number of unread messages"},"messages":{"type":"integer","description":"Total number of messages"},"attributes":{"type":"array","items":{"type":"string"},"description":"IMAP LIST attributes (e.g. Noselect, or Gmail virtual-folder flags)"}}},"MessageFolderList":{"type":"object","properties":{"mailbox":{"type":"string","format":"email"},"folders":{"type":"array","items":{"$ref":"#\/components\/schemas\/MessageFolder"}}}},"CreateMessageFolderRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Leaf name for the new folder; may not be a reserved name or contain the server's hierarchy delimiter"},"parent":{"type":"string","minLength":1,"maxLength":255,"description":"Optional raw path of an existing folder to nest the new folder under"}}},"RenameMessageFolderRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"New leaf name for the folder"}}},"MessageFolderMutationResponse":{"type":"object","properties":{"folder":{"type":"object","properties":{"name":{"type":"string"},"path":{"type":"string"}}}}},"SendMessageRequest":{"type":"object","required":["to","subject","body"],"properties":{"to":{"type":"array","minItems":1,"items":{"type":"string","format":"email"},"description":"Recipient email addresses (max 10 total across to\/cc\/bcc)"},"cc":{"type":"array","items":{"type":"string","format":"email"}},"bcc":{"type":"array","items":{"type":"string","format":"email"}},"subject":{"type":"string","maxLength":998,"description":"Email subject line. Must not contain CR or LF characters."},"body":{"type":"object","description":"At least one of text or html must be provided.","properties":{"text":{"type":"string","nullable":true,"description":"Plain text body (max 200 KB)"},"html":{"type":"string","nullable":true,"description":"HTML body (max 500 KB)"}}},"attachments":{"type":"array","maxItems":5,"description":"File attachments (max 5 files, 5 MB each, 10 MB total)","items":{"type":"object","required":["filename","content_type","content_base64"],"properties":{"filename":{"type":"string","maxLength":255},"content_type":{"type":"string","description":"MIME type (must be in allowlist)","enum":["image\/jpeg","image\/png","image\/gif","image\/webp","application\/pdf","text\/plain","text\/csv","text\/html","application\/json","application\/xml","application\/zip","application\/gzip","application\/vnd.openxmlformats-officedocument.wordprocessingml.document","application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application\/vnd.openxmlformats-officedocument.presentationml.presentation","application\/msword","application\/vnd.ms-excel","message\/rfc822"]},"content_base64":{"type":"string","format":"byte","description":"Base64-encoded file content"}}}},"reply_to_message_id":{"type":"string","nullable":true,"maxLength":500,"description":"Message-ID to reply to (sets In-Reply-To and References headers)"}}},"SendMessageResponse":{"type":"object","properties":{"status":{"type":"string","enum":["queued"]},"message_id":{"type":"string","description":"RFC 5322 Message-ID assigned to the outgoing email"},"queued_at":{"type":"string","format":"date-time"},"request_id":{"type":"string"}}},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["not_found","validation_error","insufficient_scope","token_scope_blocked_by_plan","plan_api_disabled","plan_message_api_disabled","message_token_unauthenticated","forbidden","rate_limited","idempotency_mismatch","idempotency_key_required","duplicate_mailbox","mailbox_limit_reached","mailbox_unavailable","service_unavailable","server_error","imap_error","send_blocked","sending_limit_exceeded","recipient_suppressed","intent_expired","intent_already_confirmed","missing_confirm_header","destructive_cooldown"]},"message":{"type":"string"},"hint":{"type":"string","nullable":true},"request_id":{"type":"string"},"retryable":{"type":"boolean"}},"required":["code","message","request_id","retryable"]}}},"DriveBulkRequest":{"type":"object","required":["folder_ids","file_ids"],"properties":{"folder_ids":{"type":"array","items":{"type":"integer"},"maxItems":5000,"description":"Folder ids to operate on. Empty array allowed."},"file_ids":{"type":"array","items":{"type":"integer"},"maxItems":5000,"description":"File ids to operate on. Empty array allowed."}}},"DriveDevice":{"type":"object","description":"A Drive sync-device password row. Plaintext is returned ONLY on create \/ rotate responses, never on read.","properties":{"id":{"type":"integer"},"label":{"type":"string","maxLength":64},"scopes":{"type":"array","items":{"type":"string"}},"mailbox_id":{"type":"integer","nullable":true,"description":"Null = account-wide; integer = mailbox-bound."},"created_via":{"type":"string","enum":["dashboard","webmail","api"]},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":"string","format":"date-time","nullable":true},"last_used_ip":{"type":"string","nullable":true},"expires_at":{"type":"string","format":"date-time","nullable":true},"revoked_at":{"type":"string","format":"date-time","nullable":true},"is_active":{"type":"boolean","description":"True iff not revoked and not expired."}},"required":["id","label","scopes","mailbox_id","created_via","created_at","is_active"]}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Client-supplied unique key (max 255 chars). Replays within 24h return the original response. Required by mutating endpoints; the middleware auto-rejects POST\/PUT\/PATCH\/DELETE without it on idempotent routes.","schema":{"type":"string","maxLength":255}}},"responses":{"Unauthorized":{"description":"Authentication required","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"InsufficientScope":{"description":"The token is missing a required scope for this operation","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"Forbidden":{"description":"Insufficient permissions","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"NotFound":{"description":"Resource not found","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"Gone":{"description":"Resource expired or no longer available","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"Conflict":{"description":"Resource conflict","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"ValidationError":{"description":"Validation failed","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"TooManyRequests":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}}},"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}}}}}