{
    "openapi": "3.1.0",
    "info": {
        "title": "Mailyte API",
        "version": "v1",
        "description": "The Mailyte API lets your own software do everything you can do in the Mailyte\ndashboard and webmail: send mail, manage domains and mailboxes, read delivery\nevents, run campaigns, and receive webhooks.\n\nThere are two credentials, because there are two kinds of caller.\n\nAn **organization API key** (`mk_live_\u2026`) belongs to an organization and acts on\nits behalf \u2014 this is what your application uses. A **mailbox token** belongs to\none mailbox and acts as that person, and is what the Mailbox API takes.\n\nEvery response from the organization API is wrapped in the same envelope:\n\n```json\n{ \"message\": \"\u2026\", \"data\": { }, \"success\": true, \"code\": 200 }\n```\n\n`data` holds the result. `success` and `code` restate the HTTP status so a client\nthat only reads the body can still tell what happened.",
        "contact": {
            "name": "Mailyte support",
            "url": "https://mailyte.com/contact-sales"
        },
        "license": {
            "name": "Proprietary"
        }
    },
    "servers": [
        {
            "url": "https://app.mailyte.com",
            "description": "Production"
        },
        {
            "url": "{host}",
            "description": "A self-hosted installation",
            "variables": {
                "host": {
                    "default": "https://app.example.com",
                    "description": "Your own Mailyte host"
                }
            }
        }
    ],
    "tags": [
        {
            "name": "Sending",
            "description": "Submit messages for delivery, individually or in batches."
        },
        {
            "name": "Templates",
            "description": "Stored templates with variables, rendered at send time."
        },
        {
            "name": "Domains",
            "description": "Add a sending domain, publish its DNS, and verify it."
        },
        {
            "name": "Mailboxes",
            "description": "Provision mailboxes, aliases and forwarding for a domain."
        },
        {
            "name": "Senders",
            "description": "Verified identities a message may be sent as."
        },
        {
            "name": "SMTP credentials",
            "description": "Logins for applications that relay over SMTP rather than HTTP."
        },
        {
            "name": "Events",
            "description": "What happened to a message after you submitted it."
        },
        {
            "name": "Suppressions",
            "description": "Addresses Mailyte will refuse to send to, and why."
        },
        {
            "name": "Webhooks",
            "description": "Receive delivery events at your own endpoint as they happen."
        },
        {
            "name": "Contacts",
            "description": "Contacts, lists, custom fields and segments."
        },
        {
            "name": "Campaigns",
            "description": "Bulk sends to a list or segment, scheduled and reported on."
        },
        {
            "name": "Reports",
            "description": "Deliverability, engagement and volume reporting."
        },
        {
            "name": "Transport rules",
            "description": "Organization-wide rules applied to mail in transit."
        },
        {
            "name": "Account",
            "description": "Organization usage, limits, API keys and dedicated IPs."
        },
        {
            "name": "Mailbox API",
            "description": "Everything the webmail does, for one mailbox. Takes a mailbox token, not an organization API key."
        }
    ],
    "components": {
        "securitySchemes": {
            "ApiKeyAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "An organization API key, created on the Developer page. Send it as `Authorization: Bearer mk_live_\u2026`. The key names its own organization, so no `X-Organization-ID` header is needed."
            },
            "SessionToken": {
                "type": "http",
                "scheme": "bearer",
                "description": "A signed-in user token, used by first-party applications. Requires an `X-Organization-ID` header naming the organization to act in."
            },
            "MailboxToken": {
                "type": "http",
                "scheme": "bearer",
                "description": "A mailbox token from POST /api/v1/mailbox-auth/login. Acts as one mailbox holder, not as the organization."
            }
        },
        "schemas": {
            "Envelope": {
                "type": "object",
                "description": "Every organization API response has this shape. `data` holds the result.",
                "required": [
                    "message",
                    "success",
                    "code"
                ],
                "properties": {
                    "message": {
                        "type": "string",
                        "description": "Human-readable summary of what happened."
                    },
                    "data": {
                        "description": "The result. Shape depends on the endpoint; null on most errors."
                    },
                    "success": {
                        "type": "boolean"
                    },
                    "code": {
                        "type": "integer",
                        "description": "Repeats the HTTP status code."
                    }
                }
            },
            "Scope": {
                "type": "string",
                "enum": [
                    "messages:send",
                    "templates:read",
                    "templates:write",
                    "domains:read",
                    "domains:write",
                    "mailboxes:read",
                    "mailboxes:write",
                    "senders:read",
                    "senders:write",
                    "smtp:read",
                    "smtp:write",
                    "events:read",
                    "reports:read",
                    "suppressions:read",
                    "suppressions:write",
                    "webhooks:read",
                    "webhooks:write",
                    "contacts:read",
                    "contacts:write",
                    "campaigns:read",
                    "campaigns:write",
                    "transport_rules:read",
                    "transport_rules:write",
                    "account:read"
                ]
            },
            "PaginationMeta": {
                "type": "object",
                "description": "Pagination state for a list response. The page links reflect the parameters you sent and nothing Mailyte added on the way through.",
                "properties": {
                    "current_page": {
                        "type": "integer"
                    },
                    "per_page": {
                        "type": "integer"
                    },
                    "total": {
                        "type": "integer"
                    },
                    "last_page": {
                        "type": "integer"
                    },
                    "from": {
                        "type": "integer",
                        "nullable": true
                    },
                    "to": {
                        "type": "integer",
                        "nullable": true
                    },
                    "first_page_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "last_page_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "next_page_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "prev_page_url": {
                        "type": "string",
                        "nullable": true
                    },
                    "path": {
                        "type": "string"
                    },
                    "can_load_more": {
                        "type": "boolean"
                    }
                }
            },
            "MailboxLoginRequest": {
                "properties": {
                    "email_address": {
                        "type": "string",
                        "maxLength": 255,
                        "title": "Email Address"
                    },
                    "password": {
                        "type": "string",
                        "maxLength": 1024,
                        "title": "Password"
                    },
                    "two_factor_code": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 32
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Two Factor Code"
                    }
                },
                "type": "object",
                "required": [
                    "email_address",
                    "password"
                ],
                "title": "MailboxLoginRequest"
            },
            "HTTPValidationError": {
                "properties": {
                    "detail": {
                        "items": {
                            "$ref": "#/components/schemas/ValidationError"
                        },
                        "type": "array",
                        "title": "Detail"
                    }
                },
                "type": "object",
                "title": "HTTPValidationError"
            },
            "CreateFolderRequest": {
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 255,
                        "minLength": 1,
                        "pattern": "^[^/\\\\\\x00-\\x1F]+$",
                        "title": "Name"
                    }
                },
                "type": "object",
                "required": [
                    "name"
                ],
                "title": "CreateFolderRequest"
            },
            "RenameFolderRequest": {
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 255,
                        "minLength": 1,
                        "pattern": "^[^/\\\\\\x00-\\x1F]+$",
                        "title": "Name"
                    }
                },
                "type": "object",
                "required": [
                    "name"
                ],
                "title": "RenameFolderRequest"
            },
            "SaveDraftRequest": {
                "properties": {
                    "to": {
                        "anyOf": [
                            {
                                "items": {
                                    "type": "string"
                                },
                                "type": "array"
                            },
                            {
                                "type": "string"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "To"
                    },
                    "cc": {
                        "anyOf": [
                            {
                                "items": {
                                    "type": "string"
                                },
                                "type": "array"
                            },
                            {
                                "type": "string"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Cc"
                    },
                    "bcc": {
                        "anyOf": [
                            {
                                "items": {
                                    "type": "string"
                                },
                                "type": "array"
                            },
                            {
                                "type": "string"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Bcc"
                    },
                    "subject": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 1000
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Subject"
                    },
                    "body_html": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 5000000
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Body Html"
                    },
                    "body_text": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 5000000
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Body Text"
                    },
                    "in_reply_to": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 998
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "In Reply To"
                    },
                    "references": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 4000
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "References"
                    },
                    "replace_id": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 512
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Replace Id"
                    },
                    "replaces_id": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 512
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Replaces Id"
                    }
                },
                "type": "object",
                "title": "SaveDraftRequest"
            },
            "MoveRequest": {
                "properties": {
                    "folder": {
                        "type": "string",
                        "maxLength": 255,
                        "minLength": 1,
                        "title": "Folder"
                    }
                },
                "type": "object",
                "required": [
                    "folder"
                ],
                "title": "MoveRequest"
            },
            "UpdateSettingsRequest": {
                "properties": {
                    "signature_html": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Signature Html"
                    },
                    "signature_on_reply": {
                        "anyOf": [
                            {
                                "type": "boolean"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Signature On Reply"
                    },
                    "display_density": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Display Density"
                    },
                    "undo_send_enabled": {
                        "anyOf": [
                            {
                                "type": "boolean"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Undo Send Enabled"
                    },
                    "undo_send_seconds": {
                        "anyOf": [
                            {
                                "type": "integer"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Undo Send Seconds"
                    }
                },
                "type": "object",
                "title": "UpdateSettingsRequest"
            },
            "TwoFactorCodeRequest": {
                "properties": {
                    "code": {
                        "type": "string",
                        "maxLength": 32,
                        "minLength": 4,
                        "title": "Code"
                    }
                },
                "type": "object",
                "required": [
                    "code"
                ],
                "title": "TwoFactorCodeRequest"
            },
            "AiComposeRequest": {
                "properties": {
                    "instruction": {
                        "type": "string",
                        "maxLength": 2000,
                        "minLength": 1,
                        "title": "Instruction"
                    },
                    "existing_draft": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 20000
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Existing Draft"
                    }
                },
                "type": "object",
                "required": [
                    "instruction"
                ],
                "title": "AiComposeRequest"
            },
            "ForwardingRequest": {
                "properties": {
                    "enabled": {
                        "type": "boolean",
                        "title": "Enabled",
                        "default": false
                    },
                    "addresses": {
                        "items": {
                            "type": "string"
                        },
                        "type": "array",
                        "title": "Addresses"
                    },
                    "keep_copy": {
                        "type": "boolean",
                        "title": "Keep Copy",
                        "default": true
                    }
                },
                "type": "object",
                "title": "ForwardingRequest"
            },
            "RulesRequest": {
                "properties": {
                    "rules": {
                        "items": {
                            "additionalProperties": true,
                            "type": "object"
                        },
                        "type": "array",
                        "title": "Rules"
                    }
                },
                "type": "object",
                "title": "RulesRequest"
            },
            "routes__mailbox__VacationRequest": {
                "properties": {
                    "enabled": {
                        "type": "boolean",
                        "title": "Enabled",
                        "default": false
                    },
                    "subject": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 500
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Subject"
                    },
                    "message": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 20000
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Message"
                    },
                    "start_date": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 40
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Start Date"
                    },
                    "end_date": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 40
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "End Date"
                    }
                },
                "type": "object",
                "title": "VacationRequest"
            },
            "routes__mailbox_password__PasswordChangeRequest": {
                "properties": {
                    "current_password": {
                        "type": "string",
                        "maxLength": 1024,
                        "minLength": 1,
                        "title": "Current Password"
                    },
                    "new_password": {
                        "type": "string",
                        "maxLength": 1024,
                        "minLength": 1,
                        "title": "New Password"
                    }
                },
                "type": "object",
                "required": [
                    "current_password",
                    "new_password"
                ],
                "title": "PasswordChangeRequest"
            },
            "BlockSenderRequest": {
                "properties": {
                    "address": {
                        "type": "string",
                        "maxLength": 320,
                        "minLength": 3,
                        "title": "Address"
                    }
                },
                "type": "object",
                "required": [
                    "address"
                ],
                "title": "BlockSenderRequest"
            },
            "ConsentRequest": {
                "properties": {
                    "accept_assistant": {
                        "type": "boolean",
                        "title": "Accept Assistant"
                    },
                    "accept_training": {
                        "type": "boolean",
                        "title": "Accept Training",
                        "default": false
                    },
                    "terms_version": {
                        "type": "string",
                        "maxLength": 32,
                        "minLength": 1,
                        "title": "Terms Version"
                    }
                },
                "type": "object",
                "required": [
                    "accept_assistant",
                    "terms_version"
                ],
                "title": "ConsentRequest"
            },
            "ClassifyRequest": {
                "properties": {
                    "items": {
                        "items": {
                            "$ref": "#/components/schemas/ClassifyItem"
                        },
                        "type": "array",
                        "maxItems": 20,
                        "minItems": 1,
                        "title": "Items"
                    }
                },
                "type": "object",
                "required": [
                    "items"
                ],
                "title": "ClassifyRequest"
            },
            "EventInput": {
                "properties": {
                    "summary": {
                        "type": "string",
                        "maxLength": 500,
                        "minLength": 1,
                        "title": "Summary"
                    },
                    "start": {
                        "type": "string",
                        "format": "date-time",
                        "title": "Start"
                    },
                    "end": {
                        "type": "string",
                        "format": "date-time",
                        "title": "End"
                    },
                    "timezone_id": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 64
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Timezone Id"
                    },
                    "all_day": {
                        "type": "boolean",
                        "title": "All Day",
                        "default": false
                    },
                    "description": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 20000
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Description"
                    },
                    "location": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 500
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Location"
                    },
                    "rrule": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 500
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Rrule"
                    },
                    "reminder_minutes": {
                        "anyOf": [
                            {
                                "type": "integer",
                                "maximum": 40320,
                                "minimum": 0
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Reminder Minutes"
                    },
                    "attendees": {
                        "anyOf": [
                            {
                                "items": {
                                    "additionalProperties": true,
                                    "type": "object"
                                },
                                "type": "array"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Attendees"
                    }
                },
                "type": "object",
                "required": [
                    "summary",
                    "start",
                    "end"
                ],
                "title": "EventInput"
            },
            "SubscriptionInput": {
                "properties": {
                    "calendar": {
                        "type": "string",
                        "maxLength": 200,
                        "title": "Calendar",
                        "default": "default"
                    },
                    "label": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 100
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Label"
                    }
                },
                "type": "object",
                "title": "SubscriptionInput"
            },
            "FreeBusyInput": {
                "properties": {
                    "attendees": {
                        "items": {
                            "type": "string"
                        },
                        "type": "array",
                        "maxItems": 25,
                        "minItems": 1,
                        "title": "Attendees"
                    },
                    "start": {
                        "type": "string",
                        "format": "date-time",
                        "title": "Start"
                    },
                    "end": {
                        "type": "string",
                        "format": "date-time",
                        "title": "End"
                    }
                },
                "type": "object",
                "required": [
                    "attendees",
                    "start",
                    "end"
                ],
                "title": "FreeBusyInput"
            },
            "RsvpInput": {
                "properties": {
                    "response": {
                        "type": "string",
                        "pattern": "^(accepted|declined|tentative)$",
                        "title": "Response"
                    },
                    "calendar": {
                        "type": "string",
                        "maxLength": 200,
                        "title": "Calendar",
                        "default": "default"
                    }
                },
                "type": "object",
                "required": [
                    "response"
                ],
                "title": "RsvpInput"
            },
            "ContactInput": {
                "properties": {
                    "full_name": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 255
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Full Name"
                    },
                    "first_name": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 100
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "First Name"
                    },
                    "last_name": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 100
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Last Name"
                    },
                    "emails": {
                        "items": {
                            "$ref": "#/components/schemas/EmailInput"
                        },
                        "type": "array",
                        "maxItems": 10,
                        "title": "Emails"
                    },
                    "phones": {
                        "items": {
                            "$ref": "#/components/schemas/PhoneInput"
                        },
                        "type": "array",
                        "maxItems": 10,
                        "title": "Phones"
                    },
                    "organization": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 255
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Organization"
                    },
                    "title": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 255
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Title"
                    },
                    "address": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 500
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Address"
                    },
                    "note": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 2000
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Note"
                    },
                    "birthday": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 32
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Birthday"
                    }
                },
                "type": "object",
                "title": "ContactInput",
                "description": "What the UI collects. Every field optional but one.\n\nA contact with nothing but a phone number is a real contact -- the\nbuilder's FN fallback covers the display name -- so requiring a name here\nwould reject something people legitimately save."
            },
            "ValidationError": {
                "properties": {
                    "loc": {
                        "items": {
                            "anyOf": [
                                {
                                    "type": "string"
                                },
                                {
                                    "type": "integer"
                                }
                            ]
                        },
                        "type": "array",
                        "title": "Location"
                    },
                    "msg": {
                        "type": "string",
                        "title": "Message"
                    },
                    "type": {
                        "type": "string",
                        "title": "Error Type"
                    },
                    "input": {
                        "title": "Input"
                    },
                    "ctx": {
                        "type": "object",
                        "title": "Context"
                    }
                },
                "type": "object",
                "required": [
                    "loc",
                    "msg",
                    "type"
                ],
                "title": "ValidationError"
            },
            "ClassifyItem": {
                "properties": {
                    "id": {
                        "type": "string",
                        "maxLength": 300,
                        "minLength": 1,
                        "title": "Id"
                    },
                    "subject": {
                        "type": "string",
                        "maxLength": 1000,
                        "title": "Subject",
                        "default": ""
                    },
                    "preview": {
                        "type": "string",
                        "maxLength": 2000,
                        "title": "Preview",
                        "default": ""
                    }
                },
                "type": "object",
                "required": [
                    "id"
                ],
                "title": "ClassifyItem"
            },
            "EmailInput": {
                "properties": {
                    "address": {
                        "type": "string",
                        "maxLength": 320,
                        "title": "Address"
                    },
                    "type": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 20
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Type"
                    }
                },
                "type": "object",
                "required": [
                    "address"
                ],
                "title": "EmailInput"
            },
            "PhoneInput": {
                "properties": {
                    "number": {
                        "type": "string",
                        "maxLength": 50,
                        "title": "Number"
                    },
                    "type": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 20
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Type"
                    }
                },
                "type": "object",
                "required": [
                    "number"
                ],
                "title": "PhoneInput"
            }
        },
        "responses": {
            "Unauthorized": {
                "description": "The API key is missing, unknown, revoked or expired. All four answer identically, on purpose: distinguishing them would confirm which keys exist.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Envelope"
                        },
                        "example": {
                            "message": "Invalid API key.",
                            "data": null,
                            "success": false,
                            "code": 401
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "The key is valid but may not do this: it lacks the required scope, its IP allowlist does not include you, or this endpoint does not accept API keys.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Envelope"
                        },
                        "example": {
                            "message": "This API key is missing the required scope: messages:send.",
                            "data": null,
                            "success": false,
                            "code": 403
                        }
                    }
                }
            },
            "NotFound": {
                "description": "No such resource in this organization.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Envelope"
                        },
                        "example": {
                            "message": "Not found.",
                            "data": null,
                            "success": false,
                            "code": 404
                        }
                    }
                }
            },
            "ValidationFailed": {
                "description": "The request was understood but the values were not acceptable.",
                "content": {
                    "application/json": {
                        "schema": {
                            "allOf": [
                                {
                                    "$ref": "#/components/schemas/Envelope"
                                },
                                {
                                    "type": "object",
                                    "properties": {
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            ]
                        },
                        "example": {
                            "message": "Validation failed",
                            "code": 422,
                            "success": false,
                            "errors": {
                                "to": [
                                    "The to field must be a valid email address."
                                ]
                            }
                        }
                    }
                }
            },
            "RateLimited": {
                "description": "Too many requests, or the organization has spent its sending allowance. `Retry-After` says how long to wait.",
                "headers": {
                    "Retry-After": {
                        "schema": {
                            "type": "integer"
                        },
                        "description": "Seconds to wait before retrying."
                    },
                    "X-RateLimit-Limit": {
                        "schema": {
                            "type": "integer"
                        }
                    },
                    "X-RateLimit-Remaining": {
                        "schema": {
                            "type": "integer"
                        }
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Envelope"
                        },
                        "example": {
                            "message": "Sending rate limit exceeded.",
                            "data": null,
                            "success": false,
                            "code": 429
                        }
                    }
                }
            }
        }
    },
    "security": [
        {
            "ApiKeyAuth": []
        }
    ],
    "paths": {
        "/api/v1/messages": {
            "post": {
                "operationId": "postMessages",
                "summary": "Send a message",
                "tags": [
                    "Sending"
                ],
                "x-required-scope": "messages:send",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Send a unique value \u2014 a UUID is ideal \u2014 to make this request safe to retry. If we have already answered a request with the same key and the same body, you get that exact response back with `Idempotent-Replayed: true` and nothing is sent a second time. Reusing a key with a DIFFERENT body is a 409, because answering the first response to a second message would silently swallow it. Keys are scoped to your organization and honoured for 24 hours. A 5xx does not record a key: we cannot say whether the message left, so your retry genuinely retries. Omit the header and nothing changes.",
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The message was accepted for delivery.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "message"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The opaque handle for this submission: a BARE ULID, no host and no angle brackets. `GET /email-logs/messages/{id}` resolves it immediately -- you do not have to wait for a webhook. It is NOT the Message-ID. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx: the send mints this before it records anything, so a response that carries a receipt carries a handle. If you are holding null you are not holding an accepted message."
                                                        },
                                                        "message_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The RFC 5322 Message-ID as it went out on the wire, ANGLE BRACKETS INCLUDED -- `<01JBT8XQ2M...@example.com>`. It is the header your recipient sees and the id `GET /domains/{domain}/messages/{messageId}` takes; percent-encode it in the path. `id` is the bare ULID and the two are not interchangeable: giving `id` to the archive endpoint returns 404, which is precisely what this field used to publish. Null when no sending host could be determined, never a guess."
                                                        },
                                                        "recipient": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The PRIMARY addressee, without any display name. Published as `recipient` rather than `to`, matching every event and message row in this section. It stays a single string now that a message may have several recipients, so code reading it does not change type underneath you -- read `recipients` for the whole set. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx, since `to` is required."
                                                        },
                                                        "recipients": {
                                                            "type": "object",
                                                            "description": "Everyone the message was addressed to. **`bcc` is deliberately absent**: blind recipients are recorded in your delivery log but never echoed on a receipt, which is the one response most likely to be forwarded, logged or shown to a customer.",
                                                            "properties": {
                                                                "to": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "As accepted, including any display name."
                                                                },
                                                                "cc": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Empty when none were given -- NONE, not unknown."
                                                                },
                                                                "count": {
                                                                    "type": "integer",
                                                                    "description": "To plus Cc. Excludes Bcc, which is not published here; the limit of 50 counts all three together."
                                                                }
                                                            }
                                                        },
                                                        "reply_to": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The Reply-To that went out. NULL MEANS NONE was set, in which case replies go to `from`."
                                                        },
                                                        "attachment_count": {
                                                            "type": "integer",
                                                            "description": "How many files were attached. Zero means none were sent, never that we did not look."
                                                        },
                                                        "from": {
                                                            "type": "object",
                                                            "description": "The sender. An object here, and everywhere else a sender appears, so one piece of caller code reads all of them.",
                                                            "properties": {
                                                                "email": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The address this was accepted as, echoed back. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx -- `from` is a required, validated field on the request and the receipt republishes the resolved sender's own address. It is never \"sent from nowhere\"."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The display name the message was sent with \u2014 the same one that went into the `From:` header, not a lookup done afterwards. NULL MEANS NONE: this sender has no display name set, so the message went out as a bare address. It is not \"unknown\" and it is not withheld \u2014 set a name on the sender and it appears here."
                                                                }
                                                            }
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The subject AS RENDERED -- `{{ }}` substituted, the same string that went into the header -- which is why it can differ from what you posted and why it is echoed at all. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx: the renderer falls back to the empty string, so a subjectless send is published as `\"\"`, never as null. Test for `\"\"`, not for null."
                                                        },
                                                        "submitted_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When we ACCEPTED the message, not when it was delivered. A 200 here means queued; the outcome arrives as a delivery event or a webhook. NULL WOULD MEAN UNKNOWN -- we could not read the timestamp off the recorded submission -- and never that the message is not submitted yet. A 2xx has already written the row, and its timestamp column is `NOT NULL DEFAULT current_timestamp()`, so this is not a case to code for."
                                                        },
                                                        "mode": {
                                                            "type": "string",
                                                            "enum": [
                                                                "live",
                                                                "test"
                                                            ],
                                                            "description": "Whether a real message was sent. `test` means this request was made with a TEST API KEY: it was validated exactly as a live one would be \u2014 the sender had to be verified, the recipients had to not be suppressed, the rate limit applied \u2014 and then nothing was handed to the mail server and nothing was recorded. `id`, `message_id` and `submitted_at` are null for that reason: there is no message to look up. Test mode is a property of the key, not of the request, so it cannot be switched on by a stray parameter in production code."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                },
                                "example": {
                                    "message": "Message submitted successfully",
                                    "code": 200,
                                    "success": true,
                                    "data": {
                                        "message_id": "<01JBT8XQ2M@yourdomain.com>",
                                        "event_id": "01JBT8XQ2M9WYC3K4F6R7S8T9V",
                                        "to": "ada@example.com",
                                        "from": "hello@yourdomain.com",
                                        "subject": "Your receipt from Acme",
                                        "submitted_at": "2026-09-17T10:04:11.000000Z"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Submits one message for delivery and returns as soon as it is accepted \u2014 delivery\nitself happens asynchronously, so a `200` here means \"queued\", not \"in their inbox\".\nWatch for the outcome through [delivery events](/developer/guides/handling-delivery-events)\nor a webhook.\n\nThree things have to be true before a send will work, and they are the cause of\nalmost every first-attempt failure:\n\n1. **The domain in `from` is verified.** See [Managing domains and DNS](/developer/guides/domains-and-dns).\n2. **`from` is a verified sender** belonging to your organization. An address that\n   merely sits on a verified domain is not enough; it has to exist as a sender.\n3. **The recipient is not suppressed.** Mailyte refuses sends to addresses that have\n   bounced, complained or unsubscribed, and it refuses them *before* your own list\n   logic gets a say. A suppressed recipient returns `422` and records an\n   `email.dropped` event.\n\nProvide content either directly (`subject` plus `html` and/or `text`) or by naming a\n`template_id`. If you do both, the fields you pass win over the template's.\n`variables` are substituted in either case.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "to",
                                    "from"
                                ],
                                "properties": {
                                    "to": {
                                        "oneOf": [
                                            {
                                                "type": "string"
                                            },
                                            {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        ],
                                        "description": "Recipients. A single address or a list, each either `user@example.com` or `Name <user@example.com>`. At most 50 across to, cc and bcc COMBINED \u2014 use /messages/batch beyond that, or when each recipient needs their own values."
                                    },
                                    "cc": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Carbon-copy recipients. Counts toward the same 50."
                                    },
                                    "bcc": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Blind-copy recipients. Counts toward the same 50. The addresses reach the envelope and are stripped from the message, so no recipient can see them \u2014 and they are NOT echoed on the response, because a receipt is the most likely thing to be forwarded or logged."
                                    },
                                    "from": {
                                        "type": "string",
                                        "format": "email",
                                        "description": "Must be a verified sender in your organization. The display name comes from the sender record."
                                    },
                                    "reply_to": {
                                        "type": "string",
                                        "description": "Where replies go instead of `from`. Accepts a display name."
                                    },
                                    "headers": {
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string"
                                        },
                                        "description": "Custom headers, at most 25 \u2014 for example `In-Reply-To` and `References` to thread a conversation. Headers Mailyte sets (From, To, Subject, Message-ID, DKIM-Signature, List-Unsubscribe, Bcc, X-Mailyte-*) are REFUSED with a 422 rather than silently dropped."
                                    },
                                    "attachments": {
                                        "type": "array",
                                        "description": "Files to attach. The whole message may be at most 10 MB, measured AFTER base64 encoding \u2014 the encoding inflates by roughly a third, so budget accordingly. Windows executable and script extensions are refused.",
                                        "items": {
                                            "type": "object",
                                            "required": [
                                                "name",
                                                "content"
                                            ],
                                            "properties": {
                                                "name": {
                                                    "type": "string",
                                                    "description": "Filename as the recipient sees it. Its extension is checked against the blocked list."
                                                },
                                                "content": {
                                                    "type": "string",
                                                    "format": "byte",
                                                    "description": "The file, base64 encoded."
                                                },
                                                "content_type": {
                                                    "type": "string",
                                                    "description": "MIME type. Guessed from the filename when omitted."
                                                },
                                                "content_id": {
                                                    "type": "string",
                                                    "description": "Set this to embed the file INLINE instead of attaching it, and reference it as `<img src=\"cid:THE_VALUE\">` in your html. Its presence is the only difference between an inline image and a download. The Content-ID header on the wire is generated; your `cid:` reference is rewritten to match, so use the value you set here and nothing else."
                                                }
                                            }
                                        }
                                    },
                                    "subject": {
                                        "type": "string",
                                        "maxLength": 2000,
                                        "description": "Required unless template_id is given."
                                    },
                                    "html": {
                                        "type": "string",
                                        "description": "HTML body. Required unless template_id or text is given."
                                    },
                                    "text": {
                                        "type": "string",
                                        "description": "Plain-text body. Always worth sending alongside html."
                                    },
                                    "template_id": {
                                        "type": "string",
                                        "description": "A stored template to render instead of inline content."
                                    },
                                    "variables": {
                                        "type": "object",
                                        "description": "Substituted into subject, html and text. Values are HTML-escaped in html bodies and left raw in subject and text. Write them as `{{ first_name }}`, optionally with `{{ first_name | default('there') }}`. **Mailchimp merge tags work too** \u2014 `*|FNAME|*` renders identically, so content migrated from Mailchimp does not have to be rewritten; `FNAME`, `LNAME`, `EMAIL`, `PHONE`, `ADDRESS`, `COMPANY` and `UNSUB` are recognised, and any other `*|TAG|*` matches a variable of that name whatever its capitalisation.",
                                        "additionalProperties": true
                                    },
                                    "metadata": {
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string"
                                        },
                                        "description": "Your own data, returned on every delivery event for this message and NEVER rendered into it. This is what lets you match a webhook to your own record without first storing our message_id against it \u2014 put your order id here. Not to be confused with `variables`, which ARE substituted into the subject and bodies. At most 10 fields, keys up to 20 characters and values up to 80."
                                    },
                                    "tags": {
                                        "type": "array",
                                        "maxItems": 10,
                                        "items": {
                                            "type": "string",
                                            "maxLength": 64
                                        },
                                        "description": "Your own labels, returned on the delivery events for this message. At most 10."
                                    },
                                    "tracking": {
                                        "type": "boolean",
                                        "description": "Set `false` to send this one message with no open pixel and no rewritten links. Use it for password resets, receipts and anything else a person asked for rather than subscribed to \u2014 a tracked transactional message looks like a newsletter to a mailbox provider, and gets filed like one. Defaults to true, so nothing changes unless you ask."
                                    },
                                    "stream": {
                                        "type": "string",
                                        "enum": [
                                            "marketing"
                                        ],
                                        "description": "Send over the marketing egress IP instead of the transactional one. Omit for application mail."
                                    }
                                }
                            },
                            "example": {
                                "to": [
                                    "Ada Lovelace <ada@example.com>"
                                ],
                                "cc": [
                                    "accounts@acme.com"
                                ],
                                "from": "hello@yourdomain.com",
                                "reply_to": "support@yourdomain.com",
                                "subject": "Your receipt from Acme",
                                "html": "<h1>Thanks, {{first_name}}</h1><p>Your order is on its way.</p>",
                                "text": "Thanks, {{first_name}}\nYour order is on its way.",
                                "variables": {
                                    "first_name": "Ada"
                                },
                                "tags": [
                                    "receipt"
                                ],
                                "headers": {
                                    "X-Order-Id": "ord_1234"
                                },
                                "metadata": {
                                    "order_id": "ord_1234",
                                    "tier": "pro"
                                },
                                "attachments": [
                                    {
                                        "name": "invoice.pdf",
                                        "content": "JVBERi0xLjQKJ...",
                                        "content_type": "application/pdf"
                                    }
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/messages/batch": {
            "post": {
                "operationId": "postMessagesBatch",
                "summary": "Send a batch of messages",
                "tags": [
                    "Sending"
                ],
                "x-required-scope": "messages:send",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Send a unique value \u2014 a UUID is ideal \u2014 to make this request safe to retry. If we have already answered a request with the same key and the same body, you get that exact response back with `Idempotent-Replayed: true` and nothing is sent a second time. Reusing a key with a DIFFERENT body is a 409, because answering the first response to a second message would silently swallow it. Keys are scoped to your organization and honoured for 24 hours. A 5xx does not record a key: we cannot say whether the message left, so your retry genuinely retries. Omit the header and nothing changes.",
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The batch was processed. Individual recipients may still have failed \u2014 check `failed`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "batch"
                                                            ]
                                                        },
                                                        "sent": {
                                                            "type": "integer",
                                                            "description": "Rows where `accepted` is true."
                                                        },
                                                        "failed": {
                                                            "type": "integer",
                                                            "description": "Rows where `accepted` is false. A refused recipient is a row, never a failed request: `sent + failed` always equals `results` length."
                                                        },
                                                        "results": {
                                                            "type": "array",
                                                            "description": "One row per recipient, in the order submitted.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "recipient": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Which recipient this row is about -- the address you submitted, echoed back so a row can be matched to a request entry without relying on position. NULL WOULD MEAN UNKNOWN and cannot happen: `messages[].to` is required and validated as an email before any row is built, and the row is built from that value on both the accepted and the refused path. A refused row still names its recipient -- that is the point of it -- so null here is never how a failure is reported. `error` is."
                                                                    },
                                                                    "accepted": {
                                                                        "type": "boolean",
                                                                        "description": "The ONLY field to branch on. Every row carries every key, so a missing `id` never has to be read as a success."
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The bare ULID handle for this recipient's copy -- the same thing `POST /messages` calls `id`, resolving at `GET /email-logs/messages/{id}`. Null when `accepted` is false."
                                                                    },
                                                                    "message_id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The RFC 5322 Message-ID for this recipient's copy, angle brackets included, for `GET /domains/{domain}/messages/{messageId}`. A different string from `id`, for a different endpoint. Null when `accepted` is false."
                                                                    },
                                                                    "error": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Why this one recipient was refused -- a suppression, a malformed address. Null when `accepted` is true."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                },
                                "example": {
                                    "message": "Batch processed",
                                    "code": 200,
                                    "success": true,
                                    "data": {
                                        "sent": 1,
                                        "failed": 1,
                                        "results": [
                                            {
                                                "to": "ada@example.com",
                                                "message_id": "<01JBT8XQ2M@yourdomain.com>"
                                            },
                                            {
                                                "to": "grace@example.com",
                                                "error": "Recipient is suppressed."
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "One shared template and a list of recipients, each with their own `variables`.\nUp to 500 recipients per call.\n\n**A partial failure is not an error.** Every recipient is processed independently, so\none suppressed or malformed address does not stop the rest \u2014 the call still returns\n`200` and the per-recipient outcome is in `results`. Check `failed` rather than the\nstatus code, or you will silently lose mail you believe you sent.\n\nThis is for transactional mail going to many people at once. For marketing sends to a\nlist or segment, use [campaigns](/developer/api/campaigns) instead: they add\nunsubscribe handling, review and reporting that this endpoint deliberately does not.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "messages",
                                    "from"
                                ],
                                "properties": {
                                    "messages": {
                                        "type": "array",
                                        "maxItems": 500,
                                        "items": {
                                            "type": "object",
                                            "required": [
                                                "to"
                                            ],
                                            "properties": {
                                                "to": {
                                                    "type": "string",
                                                    "format": "email"
                                                },
                                                "variables": {
                                                    "type": "object",
                                                    "additionalProperties": true
                                                }
                                            }
                                        }
                                    },
                                    "from": {
                                        "type": "string",
                                        "format": "email"
                                    },
                                    "subject": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "html": {
                                        "type": "string"
                                    },
                                    "text": {
                                        "type": "string"
                                    },
                                    "template_id": {
                                        "type": "string"
                                    },
                                    "tags": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "maxLength": 64
                                        }
                                    }
                                }
                            },
                            "example": {
                                "from": "hello@yourdomain.com",
                                "subject": "Your weekly summary",
                                "template_id": "01JBT8XQ2M9WYC3K4F6R7S8T9V",
                                "messages": [
                                    {
                                        "to": "ada@example.com",
                                        "variables": {
                                            "first_name": "Ada"
                                        }
                                    },
                                    {
                                        "to": "grace@example.com",
                                        "variables": {
                                            "first_name": "Grace"
                                        }
                                    }
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/messages/scheduled": {
            "post": {
                "operationId": "postMessagesScheduled",
                "summary": "Schedule a message",
                "tags": [
                    "Sending"
                ],
                "x-required-scope": "messages:send",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Send a unique value \u2014 a UUID is ideal \u2014 to make this request safe to retry. If we have already answered a request with the same key and the same body, you get that exact response back with `Idempotent-Replayed: true` and nothing is sent a second time. Reusing a key with a DIFFERENT body is a 409, because answering the first response to a second message would silently swallow it. Keys are scoped to your organization and honoured for 24 hours. A 5xx does not record a key: we cannot say whether the message left, so your retry genuinely retries. Omit the header and nothing changes.",
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "201 with the `scheduled_message`. Use its `id` to list, inspect or cancel it.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "A message accepted now and submitted at `send_at`. It is not a `message`: a message has left, and this has not. Once it goes, `message_id` names the message it became.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "scheduled_message"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Address this with `GET` and `DELETE /messages/scheduled/{id}`. It identifies the SCHEDULE, not the message \u2014 see `message_id`."
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "enum": [
                                                                "scheduled",
                                                                "sending",
                                                                "sent",
                                                                "cancelled",
                                                                "failed"
                                                            ],
                                                            "description": "One of: `scheduled` (waiting), `sending` (claimed for submission \u2014 the window in which cancelling is no longer possible), `sent`, `cancelled`, `failed`."
                                                        },
                                                        "mode": {
                                                            "type": "string",
                                                            "enum": [
                                                                "live",
                                                                "test"
                                                            ],
                                                            "description": "`test` when a test key accepted this message: it runs the whole flow \u2014 validation, scheduling, listing, cancelling \u2014 and submits nothing when it comes due. Captured when the message is accepted, not when it is sent, because test mode is a property of the KEY and the sweep has no key to read. `live` is the default."
                                                        },
                                                        "send_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When it is due. Honoured to the minute \u2014 we refuse a `send_at` less than 60 seconds out rather than promise a precision we do not have."
                                                        },
                                                        "from": {
                                                            "type": "string",
                                                            "description": "The sender, as scheduled."
                                                        },
                                                        "to": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "The recipients, as scheduled. `cc` and `bcc` are held but not published back \u2014 a Bcc that reappears in a readable response is a Bcc that leaked."
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "`null` MEANS NONE WAS SET \u2014 a message may legitimately have no subject, and a template supplies its own at render time."
                                                        },
                                                        "message_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The Message-ID it got when it left, for following it into the delivery log. `null` MEANS IT HAS NOT LEFT \u2014 still scheduled, cancelled, or failed. Never a placeholder."
                                                        },
                                                        "sent_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When it was submitted. `null` MEANS IT HAS NOT BEEN."
                                                        },
                                                        "cancelled_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When it was cancelled. `null` MEANS IT WAS NOT."
                                                        },
                                                        "failure_reason": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Why it could not be sent, in words. `null` MEANS NOTHING WENT WRONG \u2014 not that the reason is unknown. Only a `failed` row carries one. Suppression and rate limits are evaluated when the message leaves, not when it was accepted, so a message scheduled on Monday for somebody who unsubscribes on Tuesday fails here and says so."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When it was accepted."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Accepts a message now and submits it at `send_at`. The body is exactly `POST /messages`,\nplus `send_at`.\n\n**It is a separate endpoint, and that is deliberate.** Other providers put the delivery time\non the send call, and the cost of that is a send endpoint whose response is a message on one\ncall and a schedule on the next \u2014 two object types from one operation. Here you get a\n`message` from `/messages` and a `scheduled_message` from `/messages/scheduled`, always.\n`POST /messages` **refuses** a `send_at` rather than ignoring it: a scheduling parameter\nthat is silently dropped delivers the message immediately, to everyone, at the wrong time,\nwith nothing said.\n\n**Everything that can be checked now is checked now** \u2014 the body, the recipients, the\nattachments, the limits, and that `from` is a verified Sender of yours. A scheduled send\nthat fails validation three days later is a message that silently never went, and you find\nout from the recipient.\n\n**Suppression and rate limits are checked when it leaves, not when you schedule it.** They\nare questions about the world at the moment of delivery: somebody who unsubscribes on\nTuesday must not receive a message you scheduled on Monday. When that happens the row ends\n`failed` with `failure_reason` set, so it says what happened rather than disappearing.\n\n`send_at` must be at least 60 seconds ahead \u2014 the sweep runs every minute and we will not\npromise a precision we do not have \u2014 and at most 30 days, because the whole message,\nattachments included, is stored here until it goes.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "to",
                                    "from",
                                    "send_at"
                                ],
                                "properties": {
                                    "send_at": {
                                        "type": "string",
                                        "format": "date-time",
                                        "description": "ISO 8601. At least 60 seconds ahead, at most 30 days. A time we cannot honour is refused rather than rounded, and a past `send_at` is refused rather than sent immediately \u2014 it almost always means a timezone was dropped somewhere in your stack."
                                    }
                                },
                                "description": "Every field of `POST /messages`, plus `send_at`."
                            },
                            "example": {
                                "to": [
                                    "ada@example.com"
                                ],
                                "from": "hello@yourdomain.com",
                                "subject": "Your weekly summary",
                                "text": "Here is what happened this week.",
                                "send_at": "2026-09-21T09:00:00Z"
                            }
                        }
                    }
                }
            },
            "get": {
                "operationId": "getMessagesScheduled",
                "summary": "List scheduled messages",
                "tags": [
                    "Sending"
                ],
                "x-required-scope": "messages:send",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "One of `scheduled`, `sending`, `sent`, `cancelled`, `failed`.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Page size.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "description": "A message accepted now and submitted at `send_at`. It is not a `message`: a message has left, and this has not. Once it goes, `message_id` names the message it became.",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "scheduled_message"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Address this with `GET` and `DELETE /messages/scheduled/{id}`. It identifies the SCHEDULE, not the message \u2014 see `message_id`."
                                                                    },
                                                                    "status": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "scheduled",
                                                                            "sending",
                                                                            "sent",
                                                                            "cancelled",
                                                                            "failed"
                                                                        ],
                                                                        "description": "One of: `scheduled` (waiting), `sending` (claimed for submission \u2014 the window in which cancelling is no longer possible), `sent`, `cancelled`, `failed`."
                                                                    },
                                                                    "mode": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "live",
                                                                            "test"
                                                                        ],
                                                                        "description": "`test` when a test key accepted this message: it runs the whole flow \u2014 validation, scheduling, listing, cancelling \u2014 and submits nothing when it comes due. Captured when the message is accepted, not when it is sent, because test mode is a property of the KEY and the sweep has no key to read. `live` is the default."
                                                                    },
                                                                    "send_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "description": "When it is due. Honoured to the minute \u2014 we refuse a `send_at` less than 60 seconds out rather than promise a precision we do not have."
                                                                    },
                                                                    "from": {
                                                                        "type": "string",
                                                                        "description": "The sender, as scheduled."
                                                                    },
                                                                    "to": {
                                                                        "type": "array",
                                                                        "items": {
                                                                            "type": "string"
                                                                        },
                                                                        "description": "The recipients, as scheduled. `cc` and `bcc` are held but not published back \u2014 a Bcc that reappears in a readable response is a Bcc that leaked."
                                                                    },
                                                                    "subject": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "`null` MEANS NONE WAS SET \u2014 a message may legitimately have no subject, and a template supplies its own at render time."
                                                                    },
                                                                    "message_id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The Message-ID it got when it left, for following it into the delivery log. `null` MEANS IT HAS NOT LEFT \u2014 still scheduled, cancelled, or failed. Never a placeholder."
                                                                    },
                                                                    "sent_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When it was submitted. `null` MEANS IT HAS NOT BEEN."
                                                                    },
                                                                    "cancelled_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When it was cancelled. `null` MEANS IT WAS NOT."
                                                                    },
                                                                    "failure_reason": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Why it could not be sent, in words. `null` MEANS NOTHING WENT WRONG \u2014 not that the reason is unknown. Only a `failed` row carries one. Suppression and rate limits are evaluated when the message leaves, not when it was accepted, so a message scheduled on Monday for somebody who unsubscribes on Tuesday fails here and says so."
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "description": "When it was accepted."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Your scheduled messages, **soonest first** \u2014 the opposite order to every other list here,\nbecause this one is about what is about to happen and newest-first would bury the next send\nunder everything already gone.\n\nBodies are not echoed back. You already have the message you scheduled, and repeating up to\n10 MB of base64 attachments in every row would make the list unusable. What comes back is\nthe envelope: to, from, subject, and what is going to happen to it."
            }
        },
        "/api/v1/messages/scheduled/{scheduled}": {
            "get": {
                "operationId": "getMessagesScheduledScheduled",
                "summary": "Retrieve a message",
                "tags": [
                    "Sending"
                ],
                "x-required-scope": "messages:send",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "scheduled",
                        "in": "path",
                        "required": true,
                        "description": "The scheduled identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "A message accepted now and submitted at `send_at`. It is not a `message`: a message has left, and this has not. Once it goes, `message_id` names the message it became.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "scheduled_message"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Address this with `GET` and `DELETE /messages/scheduled/{id}`. It identifies the SCHEDULE, not the message \u2014 see `message_id`."
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "enum": [
                                                                "scheduled",
                                                                "sending",
                                                                "sent",
                                                                "cancelled",
                                                                "failed"
                                                            ],
                                                            "description": "One of: `scheduled` (waiting), `sending` (claimed for submission \u2014 the window in which cancelling is no longer possible), `sent`, `cancelled`, `failed`."
                                                        },
                                                        "mode": {
                                                            "type": "string",
                                                            "enum": [
                                                                "live",
                                                                "test"
                                                            ],
                                                            "description": "`test` when a test key accepted this message: it runs the whole flow \u2014 validation, scheduling, listing, cancelling \u2014 and submits nothing when it comes due. Captured when the message is accepted, not when it is sent, because test mode is a property of the KEY and the sweep has no key to read. `live` is the default."
                                                        },
                                                        "send_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When it is due. Honoured to the minute \u2014 we refuse a `send_at` less than 60 seconds out rather than promise a precision we do not have."
                                                        },
                                                        "from": {
                                                            "type": "string",
                                                            "description": "The sender, as scheduled."
                                                        },
                                                        "to": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "The recipients, as scheduled. `cc` and `bcc` are held but not published back \u2014 a Bcc that reappears in a readable response is a Bcc that leaked."
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "`null` MEANS NONE WAS SET \u2014 a message may legitimately have no subject, and a template supplies its own at render time."
                                                        },
                                                        "message_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The Message-ID it got when it left, for following it into the delivery log. `null` MEANS IT HAS NOT LEFT \u2014 still scheduled, cancelled, or failed. Never a placeholder."
                                                        },
                                                        "sent_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When it was submitted. `null` MEANS IT HAS NOT BEEN."
                                                        },
                                                        "cancelled_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When it was cancelled. `null` MEANS IT WAS NOT."
                                                        },
                                                        "failure_reason": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Why it could not be sent, in words. `null` MEANS NOTHING WENT WRONG \u2014 not that the reason is unknown. Only a `failed` row carries one. Suppression and rate limits are evaluated when the message leaves, not when it was accepted, so a message scheduled on Monday for somebody who unsubscribes on Tuesday fails here and says so."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When it was accepted."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteMessagesScheduledScheduled",
                "summary": "Cancel a scheduled message",
                "tags": [
                    "Sending"
                ],
                "x-required-scope": "messages:send",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "scheduled",
                        "in": "path",
                        "required": true,
                        "description": "The scheduled identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "200 with the `scheduled_message`, now `cancelled`. 422 if it is too late, naming the state it is in. 404 if it is not yours.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "A message accepted now and submitted at `send_at`. It is not a `message`: a message has left, and this has not. Once it goes, `message_id` names the message it became.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "scheduled_message"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Address this with `GET` and `DELETE /messages/scheduled/{id}`. It identifies the SCHEDULE, not the message \u2014 see `message_id`."
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "enum": [
                                                                "scheduled",
                                                                "sending",
                                                                "sent",
                                                                "cancelled",
                                                                "failed"
                                                            ],
                                                            "description": "One of: `scheduled` (waiting), `sending` (claimed for submission \u2014 the window in which cancelling is no longer possible), `sent`, `cancelled`, `failed`."
                                                        },
                                                        "mode": {
                                                            "type": "string",
                                                            "enum": [
                                                                "live",
                                                                "test"
                                                            ],
                                                            "description": "`test` when a test key accepted this message: it runs the whole flow \u2014 validation, scheduling, listing, cancelling \u2014 and submits nothing when it comes due. Captured when the message is accepted, not when it is sent, because test mode is a property of the KEY and the sweep has no key to read. `live` is the default."
                                                        },
                                                        "send_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When it is due. Honoured to the minute \u2014 we refuse a `send_at` less than 60 seconds out rather than promise a precision we do not have."
                                                        },
                                                        "from": {
                                                            "type": "string",
                                                            "description": "The sender, as scheduled."
                                                        },
                                                        "to": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "The recipients, as scheduled. `cc` and `bcc` are held but not published back \u2014 a Bcc that reappears in a readable response is a Bcc that leaked."
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "`null` MEANS NONE WAS SET \u2014 a message may legitimately have no subject, and a template supplies its own at render time."
                                                        },
                                                        "message_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The Message-ID it got when it left, for following it into the delivery log. `null` MEANS IT HAS NOT LEFT \u2014 still scheduled, cancelled, or failed. Never a placeholder."
                                                        },
                                                        "sent_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When it was submitted. `null` MEANS IT HAS NOT BEEN."
                                                        },
                                                        "cancelled_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When it was cancelled. `null` MEANS IT WAS NOT."
                                                        },
                                                        "failure_reason": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Why it could not be sent, in words. `null` MEANS NOTHING WENT WRONG \u2014 not that the reason is unknown. Only a `failed` row carries one. Suppression and rate limits are evaluated when the message leaves, not when it was accepted, so a message scheduled on Monday for somebody who unsubscribes on Tuesday fails here and says so."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When it was accepted."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Stops a message that has not been sent.\n\n**Only while its status is `scheduled`.** Once the sweep has claimed it \u2014 status `sending` \u2014\nthe message may already be on the wire, and there is no such thing as unsending. The cancel\nis then refused with a message naming the state it is actually in and, for one already sent,\nwhen it went. A success you could not act on would be worse than a refusal.\n\nThe cancel and the sweep are the same conditional update on one row, so exactly one of them\ncan win. You are never told a message was cancelled when it was not."
            }
        },
        "/api/v1/domains/{domain}/messages/{messageId}": {
            "get": {
                "operationId": "getDomainsDomainMessagesMessageId",
                "summary": "Retrieve a stored message",
                "tags": [
                    "Sending"
                ],
                "x-required-scope": "events:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "messageId",
                        "in": "path",
                        "required": true,
                        "description": "The message id exactly as it arrived, angle brackets included.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "archived_message",
                                                                "archived_message_preview"
                                                            ],
                                                            "description": "Which of the two shapes you got. `archived_message` is the default and carries `raw`; `archived_message_preview` is `?format=html` and carries the parsed fields instead. Branch on this, never on the presence of a key."
                                                        },
                                                        "message_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The RFC 5322 Message-ID, angle brackets included -- the same string a send returned and every event publishes. This endpoint's path parameter is this value, percent-encoded; the archive stores the id exactly as it arrived, which is why the brackets are kept everywhere rather than stripped for tidiness. NULL MEANS UNKNOWN -- the stored copy came back without an id we could state in full -- and never that the message had no Message-ID, because you just looked it up BY its Message-ID. The value you put in the path is the authoritative one; a null here is us failing to echo it, not a property of the message."
                                                        },
                                                        "domain": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The domain this copy is archived under. NULL MEANS UNKNOWN: the archiver returned the record without one. It is not a message that belongs to no domain -- as with `message_id`, you named the domain in the path to get here, and that value is the one to trust."
                                                        },
                                                        "archived_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "Null means we could not read a date off the stored copy, not that it was archived at the epoch."
                                                        },
                                                        "legal_hold": {
                                                            "type": "boolean",
                                                            "description": "Default shape only. True means retention cannot expire this copy."
                                                        },
                                                        "raw": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Default shape only. The `message/rfc822` bytes exactly as stored -- headers, body, MIME parts. Unsanitised: do not render it in a browser, use `?format=html` for that. NULL MEANS UNKNOWN AND IS A PROBLEM, not an empty message: the archive returned a record for this id but no bytes with it, so the copy is catalogued and its content is not readable here. There is no such thing as an archived message of zero bytes, so do not treat null as one -- retry, or fall back to `?format=raw`. On the `archived_message_preview` shape this key is ABSENT rather than null, deliberately: see `object`."
                                                        },
                                                        "headers": {
                                                            "type": "object",
                                                            "additionalProperties": {
                                                                "type": "string"
                                                            },
                                                            "description": "`?format=html` only. The parsed headers, name to value."
                                                        },
                                                        "html": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "`?format=html` only. The body DE-FANGED for display: remote resources stripped, scripts removed. The preview deliberately ships no raw copy beside it, because a payload bound for a browser one field away from the unsanitised bytes is one mistake from rendering the wrong one. NULL MEANS NONE: the message carried no HTML part -- a plain-text-only message is the ordinary case -- so render `text` instead. It does not mean de-fanging removed everything; a body stripped down to nothing still comes back as markup, not as null."
                                                        },
                                                        "text": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "`?format=html` only. The plain-text fallback. NULL MEANS NONE: the message carried no `text/plain` part, which is what an HTML-only message looks like. `html` and `text` can BOTH be null on the same message -- one with only attachments, or one the parser could make nothing of -- and that is the case to check for before rendering a preview, because there is nothing to show."
                                                        },
                                                        "attachments": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object"
                                                            },
                                                            "description": "`?format=html` only. The attachment manifest -- names, types and sizes, not the bytes."
                                                        },
                                                        "blocked_remote_count": {
                                                            "type": "integer",
                                                            "description": "`?format=html` only. How many remote images or resources were blocked while de-fanging, so a caller can say so rather than showing a silently broken layout."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "The archived copy of a message, which is what a webhook's `storage.url` points at.\n\n`messageId` is the id **exactly as it arrived**, angle brackets included. Stripping\nthem returns `404`: the archive stores the id as it was received, and a bridge that\nhelpfully removed `<` and `>` is why every inbound message 404'd here until\n2026-09-14."
            }
        },
        "/api/v1/email-templates": {
            "get": {
                "operationId": "getEmailTemplates",
                "summary": "List templates",
                "tags": [
                    "Templates"
                ],
                "x-required-scope": "templates:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "email_template"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "description": "Unique within your organization."
                                                                    },
                                                                    "subject": {
                                                                        "type": "string",
                                                                        "description": "May contain `{{ variable }}` placeholders, like the bodies. Required when the template is created and never null afterwards; an update that omits it keeps the stored one rather than clearing it."
                                                                    },
                                                                    "html": {
                                                                        "type": "string",
                                                                        "description": "The HTML body. Required on create and never null. A template with an empty body is `\"\"`, not null -- test for the empty string."
                                                                    },
                                                                    "text": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The plain-text body. READ SIDE ONLY: the write side still accepts `plain_text` and nothing else. `POST`/`PUT`/`PATCH /email-templates` and `POST /email-templates/preview` validate `plain_text` and silently discard a `text` key, so posting `text` stores nothing and reads back as `\"text\": null`. Send `plain_text`, read `text`, until that is fixed."
                                                                    },
                                                                    "variables": {
                                                                        "type": "array",
                                                                        "items": {
                                                                            "type": "string"
                                                                        },
                                                                        "description": "The `{{ }}` placeholder names found in the subject and bodies. A flat list of names -- no types, no required flags, no defaults, which is why it is not called a schema. Never null: `[]` means this template has no placeholders, not that we have not looked."
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "NULL MEANS UNKNOWN -- the stored row has no creation timestamp -- and never that the template is unsaved: you are reading it back, so it exists. The column is nullable only because Laravel's timestamps are, and every template created through the API has one."
                                                                    },
                                                                    "updated_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "NULL MEANS UNKNOWN, on the same terms as `created_at`, and never \"never edited\" -- an untouched template carries its creation time here, not null. Note that saving a template also re-derives `variables` from its content, so this moves on a create as well as an edit and is not a reliable \"has a human changed this\" signal."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Every stored template in your organization, newest first."
            },
            "post": {
                "operationId": "postEmailTemplates",
                "summary": "Create a email template",
                "tags": [
                    "Templates"
                ],
                "x-required-scope": "templates:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "email_template"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string"
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Unique within your organization."
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "description": "May contain `{{ variable }}` placeholders, like the bodies. Required when the template is created and never null afterwards; an update that omits it keeps the stored one rather than clearing it."
                                                        },
                                                        "html": {
                                                            "type": "string",
                                                            "description": "The HTML body. Required on create and never null. A template with an empty body is `\"\"`, not null -- test for the empty string."
                                                        },
                                                        "text": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The plain-text body. READ SIDE ONLY: the write side still accepts `plain_text` and nothing else. `POST`/`PUT`/`PATCH /email-templates` and `POST /email-templates/preview` validate `plain_text` and silently discard a `text` key, so posting `text` stores nothing and reads back as `\"text\": null`. Send `plain_text`, read `text`, until that is fixed."
                                                        },
                                                        "variables": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "The `{{ }}` placeholder names found in the subject and bodies. A flat list of names -- no types, no required flags, no defaults, which is why it is not called a schema. Never null: `[]` means this template has no placeholders, not that we have not looked."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "NULL MEANS UNKNOWN -- the stored row has no creation timestamp -- and never that the template is unsaved: you are reading it back, so it exists. The column is nullable only because Laravel's timestamps are, and every template created through the API has one."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "NULL MEANS UNKNOWN, on the same terms as `created_at`, and never \"never edited\" -- an untouched template carries its creation time here, not null. Note that saving a template also re-derives `variables` from its content, so this moves on a create as well as an edit and is not a reliable \"has a human changed this\" signal."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-templates/preview": {
            "post": {
                "operationId": "postEmailTemplatesPreview",
                "summary": "Preview a rendered template",
                "tags": [
                    "Templates"
                ],
                "x-required-scope": "templates:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "template_preview"
                                                            ]
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The subject with `{{ }}` substituted, as a real send would render it -- the preview runs the same renderer. NULL MEANS NONE: you supplied no `subject` to render, so there was nothing to give back. A subject you DID supply that renders away to nothing comes back as `\"\"`, not null, so the two cases stay distinguishable -- which matters, because `\"\"` usually means a `{{ }}` name you did not pass a value for."
                                                        },
                                                        "html": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Substituted values are HTML-escaped here and left raw in `subject` and `text`. NULL MEANS NONE -- no `html` was supplied to render -- and, as with `subject`, an empty render is `\"\"` rather than null. This endpoint renders ONLY what you post: it does not load a stored template, so a request carrying just a `template_id` previews nothing and every content field here is null."
                                                        },
                                                        "text": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The rendered plain-text body. The REQUEST field for it is `plain_text`, not `text`: this endpoint validates `plain_text` and drops a `text` key, so posting `text` renders nothing and returns null here."
                                                        },
                                                        "variables": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "The `{{ }}` placeholder names found in the supplied content -- what an editor builds its sample-value form from. This field was called `tags` before, which in this same module means the caller's labels on a message; they are unrelated. Names, not values: a placeholder appears here whether or not you supplied a value for it."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Renders a template with the variables you supply and returns the result without\nsending anything. Worth calling in your own test suite: it is the cheapest way to\ncatch a variable you renamed on one side and not the other."
            }
        },
        "/api/v1/email-templates/{email_template}": {
            "get": {
                "operationId": "getEmailTemplatesEmailTemplate",
                "summary": "Retrieve a email template",
                "tags": [
                    "Templates"
                ],
                "x-required-scope": "templates:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "email_template",
                        "in": "path",
                        "required": true,
                        "description": "The email template identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "email_template"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string"
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Unique within your organization."
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "description": "May contain `{{ variable }}` placeholders, like the bodies. Required when the template is created and never null afterwards; an update that omits it keeps the stored one rather than clearing it."
                                                        },
                                                        "html": {
                                                            "type": "string",
                                                            "description": "The HTML body. Required on create and never null. A template with an empty body is `\"\"`, not null -- test for the empty string."
                                                        },
                                                        "text": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The plain-text body. READ SIDE ONLY: the write side still accepts `plain_text` and nothing else. `POST`/`PUT`/`PATCH /email-templates` and `POST /email-templates/preview` validate `plain_text` and silently discard a `text` key, so posting `text` stores nothing and reads back as `\"text\": null`. Send `plain_text`, read `text`, until that is fixed."
                                                        },
                                                        "variables": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "The `{{ }}` placeholder names found in the subject and bodies. A flat list of names -- no types, no required flags, no defaults, which is why it is not called a schema. Never null: `[]` means this template has no placeholders, not that we have not looked."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "NULL MEANS UNKNOWN -- the stored row has no creation timestamp -- and never that the template is unsaved: you are reading it back, so it exists. The column is nullable only because Laravel's timestamps are, and every template created through the API has one."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "NULL MEANS UNKNOWN, on the same terms as `created_at`, and never \"never edited\" -- an untouched template carries its creation time here, not null. Note that saving a template also re-derives `variables` from its content, so this moves on a create as well as an edit and is not a reliable \"has a human changed this\" signal."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "operationId": "putEmailTemplatesEmailTemplate",
                "summary": "Update a email template",
                "tags": [
                    "Templates"
                ],
                "x-required-scope": "templates:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "email_template",
                        "in": "path",
                        "required": true,
                        "description": "The email template identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "email_template"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string"
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Unique within your organization."
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "description": "May contain `{{ variable }}` placeholders, like the bodies. Required when the template is created and never null afterwards; an update that omits it keeps the stored one rather than clearing it."
                                                        },
                                                        "html": {
                                                            "type": "string",
                                                            "description": "The HTML body. Required on create and never null. A template with an empty body is `\"\"`, not null -- test for the empty string."
                                                        },
                                                        "text": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The plain-text body. READ SIDE ONLY: the write side still accepts `plain_text` and nothing else. `POST`/`PUT`/`PATCH /email-templates` and `POST /email-templates/preview` validate `plain_text` and silently discard a `text` key, so posting `text` stores nothing and reads back as `\"text\": null`. Send `plain_text`, read `text`, until that is fixed."
                                                        },
                                                        "variables": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "The `{{ }}` placeholder names found in the subject and bodies. A flat list of names -- no types, no required flags, no defaults, which is why it is not called a schema. Never null: `[]` means this template has no placeholders, not that we have not looked."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "NULL MEANS UNKNOWN -- the stored row has no creation timestamp -- and never that the template is unsaved: you are reading it back, so it exists. The column is nullable only because Laravel's timestamps are, and every template created through the API has one."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "NULL MEANS UNKNOWN, on the same terms as `created_at`, and never \"never edited\" -- an untouched template carries its creation time here, not null. Note that saving a template also re-derives `variables` from its content, so this moves on a create as well as an edit and is not a reliable \"has a human changed this\" signal."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "operationId": "patchEmailTemplatesEmailTemplate",
                "summary": "Update a email template",
                "tags": [
                    "Templates"
                ],
                "x-required-scope": "templates:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "email_template",
                        "in": "path",
                        "required": true,
                        "description": "The email template identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "email_template"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string"
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Unique within your organization."
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "description": "May contain `{{ variable }}` placeholders, like the bodies. Required when the template is created and never null afterwards; an update that omits it keeps the stored one rather than clearing it."
                                                        },
                                                        "html": {
                                                            "type": "string",
                                                            "description": "The HTML body. Required on create and never null. A template with an empty body is `\"\"`, not null -- test for the empty string."
                                                        },
                                                        "text": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The plain-text body. READ SIDE ONLY: the write side still accepts `plain_text` and nothing else. `POST`/`PUT`/`PATCH /email-templates` and `POST /email-templates/preview` validate `plain_text` and silently discard a `text` key, so posting `text` stores nothing and reads back as `\"text\": null`. Send `plain_text`, read `text`, until that is fixed."
                                                        },
                                                        "variables": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "The `{{ }}` placeholder names found in the subject and bodies. A flat list of names -- no types, no required flags, no defaults, which is why it is not called a schema. Never null: `[]` means this template has no placeholders, not that we have not looked."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "NULL MEANS UNKNOWN -- the stored row has no creation timestamp -- and never that the template is unsaved: you are reading it back, so it exists. The column is nullable only because Laravel's timestamps are, and every template created through the API has one."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "NULL MEANS UNKNOWN, on the same terms as `created_at`, and never \"never edited\" -- an untouched template carries its creation time here, not null. Note that saving a template also re-derives `variables` from its content, so this moves on a create as well as an edit and is not a reliable \"has a human changed this\" signal."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteEmailTemplatesEmailTemplate",
                "summary": "Delete a email template",
                "tags": [
                    "Templates"
                ],
                "x-required-scope": "templates:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "email_template",
                        "in": "path",
                        "required": true,
                        "description": "The email template identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. The template is gone; messages already sent from it are unaffected, and a second delete of the same id is a 404."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains": {
            "get": {
                "operationId": "getDomains",
                "summary": "List domains",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "domain"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Unique identifier for the domain."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "description": "The domain itself, e.g. `example.com`."
                                                                    },
                                                                    "description": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "A free-text note the customer set on the domain. Null means NONE was ever given -- the column is nullable and nothing defaults it. It is not withheld and it is not unknown."
                                                                    },
                                                                    "state": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "active",
                                                                            "provisioning",
                                                                            "failed",
                                                                            "disabled"
                                                                        ],
                                                                        "description": "The one lifecycle answer. `disabled` wins over everything: a disabled domain does nothing whatever its provisioning says."
                                                                    },
                                                                    "provisioning": {
                                                                        "type": "object",
                                                                        "description": "How far this domain has got on the mail server. This is the detail behind `state`, not a second answer to it: read `state` to decide what a domain can do, and this to explain why.",
                                                                        "properties": {
                                                                            "state": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "enum": [
                                                                                    "pending",
                                                                                    "provisioning",
                                                                                    "active",
                                                                                    "failed",
                                                                                    "suspended",
                                                                                    "deleting",
                                                                                    "deleted"
                                                                                ],
                                                                                "description": "The mail-server provisioning lifecycle, a closed set: `pending` -> `provisioning` -> `active` or `failed`; `active` -> `suspended`; any live state -> `deleting` -> `deleted`. Never null for a stored domain -- the column is NOT NULL and defaults to `pending`, so every domain has one from the moment it is created. Distinct from the published `state`, which answers what the domain can do rather than where it is on the mail server."
                                                                            },
                                                                            "error": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "Why provisioning last failed. Null means NONE is recorded -- nothing has failed, or the last failure was cleared. **A non-null error does not imply `state` is `failed`.** The two are written by different code paths on different lifecycles: DNS verification writes this column while `state` tracks mail-server provisioning, so a fully active domain can carry a populated DNS error here. Read `state`, or `GET /domains/{domain}/verification-status`, before showing this to anyone."
                                                                            },
                                                                            "retryable": {
                                                                                "type": "boolean",
                                                                                "description": "Whether `POST /domains/{domain}/retry-provisioning` would do anything. True exactly when `state` is `failed`."
                                                                            }
                                                                        }
                                                                    },
                                                                    "sending": {
                                                                        "type": "object",
                                                                        "description": "Sending needs SPF and DKIM. Separate from receiving, because a customer who only relays through us must not publish an MX record.",
                                                                        "properties": {
                                                                            "enabled": {
                                                                                "type": "boolean"
                                                                            },
                                                                            "requires": {
                                                                                "type": "array",
                                                                                "items": {
                                                                                    "type": "string"
                                                                                }
                                                                            }
                                                                        }
                                                                    },
                                                                    "receiving": {
                                                                        "type": "object",
                                                                        "description": "Receiving needs MX.",
                                                                        "properties": {
                                                                            "enabled": {
                                                                                "type": "boolean"
                                                                            },
                                                                            "requires": {
                                                                                "type": "array",
                                                                                "items": {
                                                                                    "type": "string"
                                                                                }
                                                                            }
                                                                        }
                                                                    },
                                                                    "limits": {
                                                                        "type": "object",
                                                                        "description": "What this domain is allowed, as Mailyte records it. Every field here is always present and always a number -- there is no \"unlimited\" domain, and null is not how one would be expressed. Contrast `GET /domains/{domain}/limits`, which reports what the MAIL SERVER is enforcing and can genuinely answer \"unknown\".",
                                                                        "properties": {
                                                                            "storage_bytes": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "Bytes of mail this domain may store in total. Never null for a stored domain: the column is NOT NULL and defaults to 10 GB, so a cap always exists. Null is therefore not \"no limit\" and not \"unknown\" -- it is a value this endpoint does not produce."
                                                                            },
                                                                            "max_mailboxes": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many mailboxes may exist on this domain. Never null for a stored domain -- the column is NOT NULL and defaults to 50. There is no \"uncapped\" domain to express, so do not read a null as permission to create without limit."
                                                                            },
                                                                            "mailboxes_used": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many exist now. A real count, never null and never omitted: every operation that returns a domain loads it first, precisely so a listed domain and a fetched one carry the same fields. 0 means the domain genuinely has no mailboxes."
                                                                            }
                                                                        }
                                                                    },
                                                                    "defaults": {
                                                                        "type": "object",
                                                                        "description": "What a NEW mailbox on this domain inherits. Nothing here describes an existing mailbox.",
                                                                        "properties": {
                                                                            "mailbox_storage_bytes": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "Bytes each new mailbox is given. Never null for a stored domain -- the column is NOT NULL and defaults to 3 GB. Null would not mean \"unlimited\"; an unlimited mailbox is not something this field can express."
                                                                            }
                                                                        }
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    },
                                                                    "updated_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postDomains",
                "summary": "Add a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the domain."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The domain itself, e.g. `example.com`."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "A free-text note the customer set on the domain. Null means NONE was ever given -- the column is nullable and nothing defaults it. It is not withheld and it is not unknown."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "disabled"
                                                            ],
                                                            "description": "The one lifecycle answer. `disabled` wins over everything: a disabled domain does nothing whatever its provisioning says."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "How far this domain has got on the mail server. This is the detail behind `state`, not a second answer to it: read `state` to decide what a domain can do, and this to explain why.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail-server provisioning lifecycle, a closed set: `pending` -> `provisioning` -> `active` or `failed`; `active` -> `suspended`; any live state -> `deleting` -> `deleted`. Never null for a stored domain -- the column is NOT NULL and defaults to `pending`, so every domain has one from the moment it is created. Distinct from the published `state`, which answers what the domain can do rather than where it is on the mail server."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning last failed. Null means NONE is recorded -- nothing has failed, or the last failure was cleared. **A non-null error does not imply `state` is `failed`.** The two are written by different code paths on different lifecycles: DNS verification writes this column while `state` tracks mail-server provisioning, so a fully active domain can carry a populated DNS error here. Read `state`, or `GET /domains/{domain}/verification-status`, before showing this to anyone."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "Whether `POST /domains/{domain}/retry-provisioning` would do anything. True exactly when `state` is `failed`."
                                                                }
                                                            }
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "description": "Sending needs SPF and DKIM. Separate from receiving, because a customer who only relays through us must not publish an MX record.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "description": "Receiving needs MX.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "What this domain is allowed, as Mailyte records it. Every field here is always present and always a number -- there is no \"unlimited\" domain, and null is not how one would be expressed. Contrast `GET /domains/{domain}/limits`, which reports what the MAIL SERVER is enforcing and can genuinely answer \"unknown\".",
                                                            "properties": {
                                                                "storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes of mail this domain may store in total. Never null for a stored domain: the column is NOT NULL and defaults to 10 GB, so a cap always exists. Null is therefore not \"no limit\" and not \"unknown\" -- it is a value this endpoint does not produce."
                                                                },
                                                                "max_mailboxes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many mailboxes may exist on this domain. Never null for a stored domain -- the column is NOT NULL and defaults to 50. There is no \"uncapped\" domain to express, so do not read a null as permission to create without limit."
                                                                },
                                                                "mailboxes_used": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many exist now. A real count, never null and never omitted: every operation that returns a domain loads it first, precisely so a listed domain and a fetched one carry the same fields. 0 means the domain genuinely has no mailboxes."
                                                                }
                                                            }
                                                        },
                                                        "defaults": {
                                                            "type": "object",
                                                            "description": "What a NEW mailbox on this domain inherits. Nothing here describes an existing mailbox.",
                                                            "properties": {
                                                                "mailbox_storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes each new mailbox is given. Never null for a stored domain -- the column is NOT NULL and defaults to 3 GB. Null would not mean \"unlimited\"; an unlimited mailbox is not something this field can express."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Registers a domain and returns the DNS records to publish. Nothing can be sent from it\nuntil those records are live and verification has passed.\n\nAdding a domain does **not** create any mailboxes. A domain with no mailboxes accepts\ninbound mail and then has nowhere to put it, so create at least one before pointing MX\nat us."
            }
        },
        "/api/v1/domains/stats": {
            "get": {
                "operationId": "getDomainsStats",
                "summary": "Stats (domain)",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain_stats"
                                                            ]
                                                        },
                                                        "total": {
                                                            "type": "integer",
                                                            "description": "Every domain this organization holds that is not deleted or hidden."
                                                        },
                                                        "active": {
                                                            "type": "integer",
                                                            "description": "Domains marked active. Counted from a different column than a domain's published `state`, so the two can disagree."
                                                        },
                                                        "inactive": {
                                                            "type": "integer",
                                                            "description": "Domains not yet marked active -- usually awaiting DNS."
                                                        },
                                                        "dns_failed": {
                                                            "type": "integer",
                                                            "description": "Domains whose last DNS check failed. This OVERLAPS `inactive`: the three counts do not sum to `total`."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/bulk-delete": {
            "post": {
                "operationId": "postDomainsBulkDelete",
                "summary": "Bulk Delete (domain)",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "bulk_result"
                                                            ]
                                                        },
                                                        "action": {
                                                            "type": "string",
                                                            "enum": [
                                                                "verify",
                                                                "delete",
                                                                "activate",
                                                                "suspend"
                                                            ],
                                                            "description": "What was attempted against every id."
                                                        },
                                                        "requested": {
                                                            "type": "integer",
                                                            "description": "How many ids were submitted."
                                                        },
                                                        "succeeded": {
                                                            "type": "integer"
                                                        },
                                                        "failed": {
                                                            "type": "integer"
                                                        },
                                                        "results": {
                                                            "type": "array",
                                                            "description": "Every submitted id with its own outcome, in submission order. A bulk call is partial by nature: `succeeded` and `failed` both being non-zero is an ordinary result, not an error.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The domain id as submitted. Null on a failure the operation could not attribute to one."
                                                                    },
                                                                    "status": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "succeeded",
                                                                            "failed"
                                                                        ]
                                                                    },
                                                                    "error": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Why this one failed. Null when it succeeded."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/bulk-update": {
            "post": {
                "operationId": "postDomainsBulkUpdate",
                "summary": "Bulk Update (domain)",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "bulk_result"
                                                            ]
                                                        },
                                                        "action": {
                                                            "type": "string",
                                                            "enum": [
                                                                "verify",
                                                                "delete",
                                                                "activate",
                                                                "suspend"
                                                            ],
                                                            "description": "What was attempted against every id."
                                                        },
                                                        "requested": {
                                                            "type": "integer",
                                                            "description": "How many ids were submitted."
                                                        },
                                                        "succeeded": {
                                                            "type": "integer"
                                                        },
                                                        "failed": {
                                                            "type": "integer"
                                                        },
                                                        "results": {
                                                            "type": "array",
                                                            "description": "Every submitted id with its own outcome, in submission order. A bulk call is partial by nature: `succeeded` and `failed` both being non-zero is an ordinary result, not an error.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The domain id as submitted. Null on a failure the operation could not attribute to one."
                                                                    },
                                                                    "status": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "succeeded",
                                                                            "failed"
                                                                        ]
                                                                    },
                                                                    "error": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Why this one failed. Null when it succeeded."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/bulk-verify": {
            "post": {
                "operationId": "postDomainsBulkVerify",
                "summary": "Bulk Verify (domain)",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "bulk_result"
                                                            ]
                                                        },
                                                        "action": {
                                                            "type": "string",
                                                            "enum": [
                                                                "verify",
                                                                "delete",
                                                                "activate",
                                                                "suspend"
                                                            ],
                                                            "description": "What was attempted against every id."
                                                        },
                                                        "requested": {
                                                            "type": "integer",
                                                            "description": "How many ids were submitted."
                                                        },
                                                        "succeeded": {
                                                            "type": "integer"
                                                        },
                                                        "failed": {
                                                            "type": "integer"
                                                        },
                                                        "results": {
                                                            "type": "array",
                                                            "description": "Every submitted id with its own outcome, in submission order. A bulk call is partial by nature: `succeeded` and `failed` both being non-zero is an ordinary result, not an error.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The domain id as submitted. Null on a failure the operation could not attribute to one."
                                                                    },
                                                                    "status": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "succeeded",
                                                                            "failed"
                                                                        ]
                                                                    },
                                                                    "error": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Why this one failed. Null when it succeeded."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}": {
            "get": {
                "operationId": "getDomainsDomain",
                "summary": "Retrieve a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the domain."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The domain itself, e.g. `example.com`."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "A free-text note the customer set on the domain. Null means NONE was ever given -- the column is nullable and nothing defaults it. It is not withheld and it is not unknown."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "disabled"
                                                            ],
                                                            "description": "The one lifecycle answer. `disabled` wins over everything: a disabled domain does nothing whatever its provisioning says."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "How far this domain has got on the mail server. This is the detail behind `state`, not a second answer to it: read `state` to decide what a domain can do, and this to explain why.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail-server provisioning lifecycle, a closed set: `pending` -> `provisioning` -> `active` or `failed`; `active` -> `suspended`; any live state -> `deleting` -> `deleted`. Never null for a stored domain -- the column is NOT NULL and defaults to `pending`, so every domain has one from the moment it is created. Distinct from the published `state`, which answers what the domain can do rather than where it is on the mail server."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning last failed. Null means NONE is recorded -- nothing has failed, or the last failure was cleared. **A non-null error does not imply `state` is `failed`.** The two are written by different code paths on different lifecycles: DNS verification writes this column while `state` tracks mail-server provisioning, so a fully active domain can carry a populated DNS error here. Read `state`, or `GET /domains/{domain}/verification-status`, before showing this to anyone."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "Whether `POST /domains/{domain}/retry-provisioning` would do anything. True exactly when `state` is `failed`."
                                                                }
                                                            }
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "description": "Sending needs SPF and DKIM. Separate from receiving, because a customer who only relays through us must not publish an MX record.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "description": "Receiving needs MX.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "What this domain is allowed, as Mailyte records it. Every field here is always present and always a number -- there is no \"unlimited\" domain, and null is not how one would be expressed. Contrast `GET /domains/{domain}/limits`, which reports what the MAIL SERVER is enforcing and can genuinely answer \"unknown\".",
                                                            "properties": {
                                                                "storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes of mail this domain may store in total. Never null for a stored domain: the column is NOT NULL and defaults to 10 GB, so a cap always exists. Null is therefore not \"no limit\" and not \"unknown\" -- it is a value this endpoint does not produce."
                                                                },
                                                                "max_mailboxes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many mailboxes may exist on this domain. Never null for a stored domain -- the column is NOT NULL and defaults to 50. There is no \"uncapped\" domain to express, so do not read a null as permission to create without limit."
                                                                },
                                                                "mailboxes_used": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many exist now. A real count, never null and never omitted: every operation that returns a domain loads it first, precisely so a listed domain and a fetched one carry the same fields. 0 means the domain genuinely has no mailboxes."
                                                                }
                                                            }
                                                        },
                                                        "defaults": {
                                                            "type": "object",
                                                            "description": "What a NEW mailbox on this domain inherits. Nothing here describes an existing mailbox.",
                                                            "properties": {
                                                                "mailbox_storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes each new mailbox is given. Never null for a stored domain -- the column is NOT NULL and defaults to 3 GB. Null would not mean \"unlimited\"; an unlimited mailbox is not something this field can express."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "operationId": "putDomainsDomain",
                "summary": "Update a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the domain."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The domain itself, e.g. `example.com`."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "A free-text note the customer set on the domain. Null means NONE was ever given -- the column is nullable and nothing defaults it. It is not withheld and it is not unknown."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "disabled"
                                                            ],
                                                            "description": "The one lifecycle answer. `disabled` wins over everything: a disabled domain does nothing whatever its provisioning says."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "How far this domain has got on the mail server. This is the detail behind `state`, not a second answer to it: read `state` to decide what a domain can do, and this to explain why.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail-server provisioning lifecycle, a closed set: `pending` -> `provisioning` -> `active` or `failed`; `active` -> `suspended`; any live state -> `deleting` -> `deleted`. Never null for a stored domain -- the column is NOT NULL and defaults to `pending`, so every domain has one from the moment it is created. Distinct from the published `state`, which answers what the domain can do rather than where it is on the mail server."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning last failed. Null means NONE is recorded -- nothing has failed, or the last failure was cleared. **A non-null error does not imply `state` is `failed`.** The two are written by different code paths on different lifecycles: DNS verification writes this column while `state` tracks mail-server provisioning, so a fully active domain can carry a populated DNS error here. Read `state`, or `GET /domains/{domain}/verification-status`, before showing this to anyone."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "Whether `POST /domains/{domain}/retry-provisioning` would do anything. True exactly when `state` is `failed`."
                                                                }
                                                            }
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "description": "Sending needs SPF and DKIM. Separate from receiving, because a customer who only relays through us must not publish an MX record.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "description": "Receiving needs MX.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "What this domain is allowed, as Mailyte records it. Every field here is always present and always a number -- there is no \"unlimited\" domain, and null is not how one would be expressed. Contrast `GET /domains/{domain}/limits`, which reports what the MAIL SERVER is enforcing and can genuinely answer \"unknown\".",
                                                            "properties": {
                                                                "storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes of mail this domain may store in total. Never null for a stored domain: the column is NOT NULL and defaults to 10 GB, so a cap always exists. Null is therefore not \"no limit\" and not \"unknown\" -- it is a value this endpoint does not produce."
                                                                },
                                                                "max_mailboxes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many mailboxes may exist on this domain. Never null for a stored domain -- the column is NOT NULL and defaults to 50. There is no \"uncapped\" domain to express, so do not read a null as permission to create without limit."
                                                                },
                                                                "mailboxes_used": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many exist now. A real count, never null and never omitted: every operation that returns a domain loads it first, precisely so a listed domain and a fetched one carry the same fields. 0 means the domain genuinely has no mailboxes."
                                                                }
                                                            }
                                                        },
                                                        "defaults": {
                                                            "type": "object",
                                                            "description": "What a NEW mailbox on this domain inherits. Nothing here describes an existing mailbox.",
                                                            "properties": {
                                                                "mailbox_storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes each new mailbox is given. Never null for a stored domain -- the column is NOT NULL and defaults to 3 GB. Null would not mean \"unlimited\"; an unlimited mailbox is not something this field can express."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "operationId": "patchDomainsDomain",
                "summary": "Update a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the domain."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The domain itself, e.g. `example.com`."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "A free-text note the customer set on the domain. Null means NONE was ever given -- the column is nullable and nothing defaults it. It is not withheld and it is not unknown."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "disabled"
                                                            ],
                                                            "description": "The one lifecycle answer. `disabled` wins over everything: a disabled domain does nothing whatever its provisioning says."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "How far this domain has got on the mail server. This is the detail behind `state`, not a second answer to it: read `state` to decide what a domain can do, and this to explain why.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail-server provisioning lifecycle, a closed set: `pending` -> `provisioning` -> `active` or `failed`; `active` -> `suspended`; any live state -> `deleting` -> `deleted`. Never null for a stored domain -- the column is NOT NULL and defaults to `pending`, so every domain has one from the moment it is created. Distinct from the published `state`, which answers what the domain can do rather than where it is on the mail server."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning last failed. Null means NONE is recorded -- nothing has failed, or the last failure was cleared. **A non-null error does not imply `state` is `failed`.** The two are written by different code paths on different lifecycles: DNS verification writes this column while `state` tracks mail-server provisioning, so a fully active domain can carry a populated DNS error here. Read `state`, or `GET /domains/{domain}/verification-status`, before showing this to anyone."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "Whether `POST /domains/{domain}/retry-provisioning` would do anything. True exactly when `state` is `failed`."
                                                                }
                                                            }
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "description": "Sending needs SPF and DKIM. Separate from receiving, because a customer who only relays through us must not publish an MX record.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "description": "Receiving needs MX.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "What this domain is allowed, as Mailyte records it. Every field here is always present and always a number -- there is no \"unlimited\" domain, and null is not how one would be expressed. Contrast `GET /domains/{domain}/limits`, which reports what the MAIL SERVER is enforcing and can genuinely answer \"unknown\".",
                                                            "properties": {
                                                                "storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes of mail this domain may store in total. Never null for a stored domain: the column is NOT NULL and defaults to 10 GB, so a cap always exists. Null is therefore not \"no limit\" and not \"unknown\" -- it is a value this endpoint does not produce."
                                                                },
                                                                "max_mailboxes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many mailboxes may exist on this domain. Never null for a stored domain -- the column is NOT NULL and defaults to 50. There is no \"uncapped\" domain to express, so do not read a null as permission to create without limit."
                                                                },
                                                                "mailboxes_used": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many exist now. A real count, never null and never omitted: every operation that returns a domain loads it first, precisely so a listed domain and a fetched one carry the same fields. 0 means the domain genuinely has no mailboxes."
                                                                }
                                                            }
                                                        },
                                                        "defaults": {
                                                            "type": "object",
                                                            "description": "What a NEW mailbox on this domain inherits. Nothing here describes an existing mailbox.",
                                                            "properties": {
                                                                "mailbox_storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes each new mailbox is given. Never null for a stored domain -- the column is NOT NULL and defaults to 3 GB. Null would not mean \"unlimited\"; an unlimited mailbox is not something this field can express."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteDomainsDomain",
                "summary": "Delete a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. The domain and its mailboxes are removed."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/overview": {
            "get": {
                "operationId": "getDomainsDomainOverview",
                "summary": "Overview a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain_overview"
                                                            ]
                                                        },
                                                        "domain_id": {
                                                            "type": "string"
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The domain itself, e.g. `example.com`."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "disabled"
                                                            ],
                                                            "description": "The same lifecycle answer `GET /domains/{domain}` publishes, derived from the same fields."
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "description": "Identical to `sending` on the domain itself.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "spf",
                                                                            "dkim"
                                                                        ]
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "description": "Identical to `receiving` on the domain itself.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "mx"
                                                                        ]
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "mailboxes": {
                                                            "type": "object",
                                                            "description": "Live counts over this domain's mailbox rows. None of the three is ever null, and `active` + `suspended` need not sum to `total` -- a mailbox in any other status is counted only in `total`.",
                                                            "properties": {
                                                                "total": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Mailboxes on this domain. A live `COUNT`, never null; 0 means the domain genuinely has none."
                                                                },
                                                                "active": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Of those, how many are active. A live `COUNT`, never null; 0 is a measured zero."
                                                                },
                                                                "suspended": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Of those, how many are suspended. A live `COUNT`, never null; 0 is a measured zero, not an unread figure."
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "properties": {
                                                                "used_percent": {
                                                                    "type": "number",
                                                                    "nullable": true,
                                                                    "description": "Storage used across this domain's mailboxes as a percentage of the domain quota. Null when no quota is set -- there is nothing to be a percentage of."
                                                                }
                                                            }
                                                        },
                                                        "health_score": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "0-100. The same score `GET /domains/{domain}/health` returns, where the issues behind it are also listed. Never null: it is computed on every request by deducting from 100 for each problem found, so a domain with nothing wrong scores 100 and one that could not be judged still scores. A low score is a verdict, never a missing reading."
                                                        },
                                                        "checked_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When DNS was last resolved for this domain. Null when it never has been."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/dns-records": {
            "get": {
                "operationId": "getDomainsDomainDnsRecords",
                "summary": "Get the DNS records to publish",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "dns_records"
                                                            ]
                                                        },
                                                        "domain": {
                                                            "type": "string",
                                                            "description": "The domain these records belong to."
                                                        },
                                                        "records": {
                                                            "type": "array",
                                                            "description": "Every record to publish, required and optional together. Read `required_for` to tell them apart.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "purpose": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "enum": [
                                                                            "spf",
                                                                            "dkim",
                                                                            "mx",
                                                                            "dmarc",
                                                                            "autodiscover",
                                                                            "autoconfig",
                                                                            "_autodiscover"
                                                                        ],
                                                                        "description": "What the record is for. Joins to `checks` on the verification endpoint for the four that are checked. Never null: every record this endpoint builds is built with its purpose, and a record whose purpose could not be named would not be publishable advice. The set is closed -- a value outside it is a bug, not a new record type to guess at."
                                                                    },
                                                                    "type": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "txt",
                                                                            "mx",
                                                                            "cname",
                                                                            "srv",
                                                                            "a"
                                                                        ],
                                                                        "description": "The DNS record type, lowercased. DNS is case-insensitive about these, so it can be pasted into any console as-is."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "description": "The fully qualified name to create."
                                                                    },
                                                                    "value": {
                                                                        "type": "string",
                                                                        "description": "The value, verbatim. Do not reformat it."
                                                                    },
                                                                    "priority": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "MX and SRV only. Null where the type has no priority -- not 0, which is a real and highest priority."
                                                                    },
                                                                    "required_for": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "enum": [
                                                                            "sending",
                                                                            "receiving"
                                                                        ],
                                                                        "description": "Which capability this record unlocks. Null means optional: recommended, or a mail-client convenience, but nothing stops working without it."
                                                                    },
                                                                    "description": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "One line explaining what this record does, safe to show a customer. Never null -- every record is built with one. It explains the record's PURPOSE and says nothing about whether it has been published or has passed; that is `GET /domains/{domain}/verification-status`."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "fetched_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When these values were last read from the mail server. They change rarely; null means they have never been fetched."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "The records this domain needs, with their current observed state.\n\nSending needs **SPF and DKIM**; MX is only needed to *receive*. Mailyte tracks those\nseparately (`dns_verified` and `mx_verified`) precisely so a customer who sends through\nus but keeps their mailboxes elsewhere is not blocked on an MX record they must not\npublish."
            }
        },
        "/api/v1/domains/{domain}/dkim": {
            "get": {
                "operationId": "getDomainsDomainDkim",
                "summary": "Dkim a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "dkim_key"
                                                            ]
                                                        },
                                                        "domain_id": {
                                                            "type": "string"
                                                        },
                                                        "enabled": {
                                                            "type": "boolean",
                                                            "description": "Whether a signing key has been generated. Not whether the record is published -- that is `checks.dkim.verified` on the verification endpoint."
                                                        },
                                                        "selector": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The DKIM selector, which together with the domain forms the record name. Always the literal `default`: nothing in this product lets a caller choose one, so it is never null and never varies. It is published because a caller building the record name needs it, not because it is a setting. Present even when no key has been generated -- read `enabled` for that, not this."
                                                        },
                                                        "record": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The record to publish, or null when no key has been generated yet.",
                                                            "properties": {
                                                                "type": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "txt"
                                                                    ]
                                                                },
                                                                "name": {
                                                                    "type": "string"
                                                                },
                                                                "value": {
                                                                    "type": "string",
                                                                    "description": "The public key record. The private half never leaves the mail server."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/dns-provider": {
            "get": {
                "operationId": "getDomainsDomainDnsProvider",
                "summary": "Dns Provider a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "dns_provider"
                                                            ]
                                                        },
                                                        "nameservers": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "The domain's NS records. Empty when the domain does not resolve."
                                                        },
                                                        "provider": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Null when the nameservers match no provider we recognise. That is an ordinary answer, not an error.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string",
                                                                    "description": "A stable slug, e.g. `cloudflare`."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "description": "The provider's own name, for display."
                                                                },
                                                                "dns_panel_url": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A deep link to this domain's DNS settings. Null means NONE exists to give: we recognised the provider, but it has no URL shape we can fill in reliably. It is not unknown and not an error -- the provider is identified either way, so send the customer to `provider.name` by hand rather than showing a failure."
                                                                }
                                                            }
                                                        },
                                                        "domain_connect": {
                                                            "type": "object",
                                                            "description": "Whether the provider advertises the Domain Connect standard, which can apply the records without the customer typing them.",
                                                            "properties": {
                                                                "supported": {
                                                                    "type": "boolean",
                                                                    "description": "Whether a `_domainconnect` discovery record was found. False also covers the case where the lookup itself failed, so it means \"not detected\" rather than \"confirmed absent\"."
                                                                },
                                                                "settings_url": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Where to send the customer to apply the records automatically. Null exactly when `supported` is false, and means NONE was discovered -- never that it exists but was withheld. The two fields move together, so branch on `supported` and use this only inside that branch."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/verification-status": {
            "get": {
                "operationId": "getDomainsDomainVerificationStatus",
                "summary": "Verification Status a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain_verification"
                                                            ]
                                                        },
                                                        "domain_id": {
                                                            "type": "string"
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean",
                                                                    "description": "Whether this domain may send. The same value as `sending.enabled` on the domain itself."
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "spf",
                                                                            "dkim"
                                                                        ]
                                                                    },
                                                                    "description": "The records in `checks` that must pass for this verdict. The same list `GET /domains/{domain}` publishes."
                                                                },
                                                                "message": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why this verdict is false, or null when it is true. One record at a time: the first failure, not every failure."
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean",
                                                                    "description": "Whether mail addressed to this domain is delivered here. A send-only domain is expected to be false, and that is not a fault."
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "mx"
                                                                        ]
                                                                    },
                                                                    "description": "The records in `checks` that must pass for this verdict. The same list `GET /domains/{domain}` publishes."
                                                                },
                                                                "message": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why this verdict is false, or null when it is true. One record at a time: the first failure, not every failure."
                                                                }
                                                            }
                                                        },
                                                        "checks": {
                                                            "type": "object",
                                                            "description": "One entry per record, always all four, whether or not the mail server had an answer for it.",
                                                            "properties": {
                                                                "spf": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "required_for": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "enum": [
                                                                                "sending",
                                                                                "receiving"
                                                                            ],
                                                                            "description": "Which verdict this record feeds. null means it is reported but blocks nothing."
                                                                        },
                                                                        "verified": {
                                                                            "type": "boolean"
                                                                        },
                                                                        "message": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "What is wrong with the record, when the mail server said. Null is \"no comment\", not \"no problem\"."
                                                                        }
                                                                    }
                                                                },
                                                                "dkim": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "required_for": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "enum": [
                                                                                "sending",
                                                                                "receiving"
                                                                            ],
                                                                            "description": "Which verdict this record feeds. null means it is reported but blocks nothing."
                                                                        },
                                                                        "verified": {
                                                                            "type": "boolean"
                                                                        },
                                                                        "message": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "What is wrong with the record, when the mail server said. Null is \"no comment\", not \"no problem\"."
                                                                        }
                                                                    }
                                                                },
                                                                "mx": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "required_for": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "enum": [
                                                                                "sending",
                                                                                "receiving"
                                                                            ],
                                                                            "description": "Which verdict this record feeds. null means it is reported but blocks nothing."
                                                                        },
                                                                        "verified": {
                                                                            "type": "boolean"
                                                                        },
                                                                        "message": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "What is wrong with the record, when the mail server said. Null is \"no comment\", not \"no problem\"."
                                                                        }
                                                                    }
                                                                },
                                                                "dmarc": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "required_for": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "enum": [
                                                                                "sending",
                                                                                "receiving"
                                                                            ],
                                                                            "description": "Which verdict this record feeds. null means it is reported but blocks nothing."
                                                                        },
                                                                        "verified": {
                                                                            "type": "boolean"
                                                                        },
                                                                        "message": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "What is wrong with the record, when the mail server said. Null is \"no comment\", not \"no problem\"."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "advisory": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "Things worth doing that block nothing -- publishing DMARC, pointing MX here. Empty on a status read, which composes none."
                                                        },
                                                        "checked_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the mail server last resolved these records. Null when it never has, NOT the time of this request."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/verify": {
            "post": {
                "operationId": "postDomainsDomainVerify",
                "summary": "Verify a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain_verification"
                                                            ]
                                                        },
                                                        "domain_id": {
                                                            "type": "string"
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean",
                                                                    "description": "Whether this domain may send. The same value as `sending.enabled` on the domain itself."
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "spf",
                                                                            "dkim"
                                                                        ]
                                                                    },
                                                                    "description": "The records in `checks` that must pass for this verdict. The same list `GET /domains/{domain}` publishes."
                                                                },
                                                                "message": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why this verdict is false, or null when it is true. One record at a time: the first failure, not every failure."
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean",
                                                                    "description": "Whether mail addressed to this domain is delivered here. A send-only domain is expected to be false, and that is not a fault."
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "mx"
                                                                        ]
                                                                    },
                                                                    "description": "The records in `checks` that must pass for this verdict. The same list `GET /domains/{domain}` publishes."
                                                                },
                                                                "message": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why this verdict is false, or null when it is true. One record at a time: the first failure, not every failure."
                                                                }
                                                            }
                                                        },
                                                        "checks": {
                                                            "type": "object",
                                                            "description": "One entry per record, always all four, whether or not the mail server had an answer for it.",
                                                            "properties": {
                                                                "spf": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "required_for": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "enum": [
                                                                                "sending",
                                                                                "receiving"
                                                                            ],
                                                                            "description": "Which verdict this record feeds. null means it is reported but blocks nothing."
                                                                        },
                                                                        "verified": {
                                                                            "type": "boolean"
                                                                        },
                                                                        "message": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "What is wrong with the record, when the mail server said. Null is \"no comment\", not \"no problem\"."
                                                                        }
                                                                    }
                                                                },
                                                                "dkim": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "required_for": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "enum": [
                                                                                "sending",
                                                                                "receiving"
                                                                            ],
                                                                            "description": "Which verdict this record feeds. null means it is reported but blocks nothing."
                                                                        },
                                                                        "verified": {
                                                                            "type": "boolean"
                                                                        },
                                                                        "message": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "What is wrong with the record, when the mail server said. Null is \"no comment\", not \"no problem\"."
                                                                        }
                                                                    }
                                                                },
                                                                "mx": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "required_for": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "enum": [
                                                                                "sending",
                                                                                "receiving"
                                                                            ],
                                                                            "description": "Which verdict this record feeds. null means it is reported but blocks nothing."
                                                                        },
                                                                        "verified": {
                                                                            "type": "boolean"
                                                                        },
                                                                        "message": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "What is wrong with the record, when the mail server said. Null is \"no comment\", not \"no problem\"."
                                                                        }
                                                                    }
                                                                },
                                                                "dmarc": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "required_for": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "enum": [
                                                                                "sending",
                                                                                "receiving"
                                                                            ],
                                                                            "description": "Which verdict this record feeds. null means it is reported but blocks nothing."
                                                                        },
                                                                        "verified": {
                                                                            "type": "boolean"
                                                                        },
                                                                        "message": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "What is wrong with the record, when the mail server said. Null is \"no comment\", not \"no problem\"."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "advisory": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "Things worth doing that block nothing -- publishing DMARC, pointing MX here. Empty on a status read, which composes none."
                                                        },
                                                        "checked_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the mail server last resolved these records. Null when it never has, NOT the time of this request."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Re-checks this domain's DNS now rather than waiting for the scheduled sweep. Safe to\ncall repeatedly.\n\nDNS propagation is not instant and is not uniform \u2014 a record your own resolver can see\nmay not be visible to ours yet. If verification fails on a record you are certain is\npublished, wait and call again before assuming the value is wrong."
            }
        },
        "/api/v1/domains/{domain}/send-records": {
            "post": {
                "operationId": "postDomainsDomainSendRecords",
                "summary": "Send Records a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "dns_instructions"
                                                            ]
                                                        },
                                                        "sent_to": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "The one address written to, lowercased. This endpoint sends to exactly one recipient and builds the body itself."
                                                        },
                                                        "sent_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When the message was accepted for delivery, not when it arrived."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/sync": {
            "post": {
                "operationId": "postDomainsDomainSync",
                "summary": "Sync a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the domain."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The domain itself, e.g. `example.com`."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "A free-text note the customer set on the domain. Null means NONE was ever given -- the column is nullable and nothing defaults it. It is not withheld and it is not unknown."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "disabled"
                                                            ],
                                                            "description": "The one lifecycle answer. `disabled` wins over everything: a disabled domain does nothing whatever its provisioning says."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "How far this domain has got on the mail server. This is the detail behind `state`, not a second answer to it: read `state` to decide what a domain can do, and this to explain why.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail-server provisioning lifecycle, a closed set: `pending` -> `provisioning` -> `active` or `failed`; `active` -> `suspended`; any live state -> `deleting` -> `deleted`. Never null for a stored domain -- the column is NOT NULL and defaults to `pending`, so every domain has one from the moment it is created. Distinct from the published `state`, which answers what the domain can do rather than where it is on the mail server."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning last failed. Null means NONE is recorded -- nothing has failed, or the last failure was cleared. **A non-null error does not imply `state` is `failed`.** The two are written by different code paths on different lifecycles: DNS verification writes this column while `state` tracks mail-server provisioning, so a fully active domain can carry a populated DNS error here. Read `state`, or `GET /domains/{domain}/verification-status`, before showing this to anyone."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "Whether `POST /domains/{domain}/retry-provisioning` would do anything. True exactly when `state` is `failed`."
                                                                }
                                                            }
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "description": "Sending needs SPF and DKIM. Separate from receiving, because a customer who only relays through us must not publish an MX record.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "description": "Receiving needs MX.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "What this domain is allowed, as Mailyte records it. Every field here is always present and always a number -- there is no \"unlimited\" domain, and null is not how one would be expressed. Contrast `GET /domains/{domain}/limits`, which reports what the MAIL SERVER is enforcing and can genuinely answer \"unknown\".",
                                                            "properties": {
                                                                "storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes of mail this domain may store in total. Never null for a stored domain: the column is NOT NULL and defaults to 10 GB, so a cap always exists. Null is therefore not \"no limit\" and not \"unknown\" -- it is a value this endpoint does not produce."
                                                                },
                                                                "max_mailboxes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many mailboxes may exist on this domain. Never null for a stored domain -- the column is NOT NULL and defaults to 50. There is no \"uncapped\" domain to express, so do not read a null as permission to create without limit."
                                                                },
                                                                "mailboxes_used": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many exist now. A real count, never null and never omitted: every operation that returns a domain loads it first, precisely so a listed domain and a fetched one carry the same fields. 0 means the domain genuinely has no mailboxes."
                                                                }
                                                            }
                                                        },
                                                        "defaults": {
                                                            "type": "object",
                                                            "description": "What a NEW mailbox on this domain inherits. Nothing here describes an existing mailbox.",
                                                            "properties": {
                                                                "mailbox_storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes each new mailbox is given. Never null for a stored domain -- the column is NOT NULL and defaults to 3 GB. Null would not mean \"unlimited\"; an unlimited mailbox is not something this field can express."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/enable": {
            "post": {
                "operationId": "postDomainsDomainEnable",
                "summary": "Enable a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the domain."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The domain itself, e.g. `example.com`."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "A free-text note the customer set on the domain. Null means NONE was ever given -- the column is nullable and nothing defaults it. It is not withheld and it is not unknown."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "disabled"
                                                            ],
                                                            "description": "The one lifecycle answer. `disabled` wins over everything: a disabled domain does nothing whatever its provisioning says."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "How far this domain has got on the mail server. This is the detail behind `state`, not a second answer to it: read `state` to decide what a domain can do, and this to explain why.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail-server provisioning lifecycle, a closed set: `pending` -> `provisioning` -> `active` or `failed`; `active` -> `suspended`; any live state -> `deleting` -> `deleted`. Never null for a stored domain -- the column is NOT NULL and defaults to `pending`, so every domain has one from the moment it is created. Distinct from the published `state`, which answers what the domain can do rather than where it is on the mail server."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning last failed. Null means NONE is recorded -- nothing has failed, or the last failure was cleared. **A non-null error does not imply `state` is `failed`.** The two are written by different code paths on different lifecycles: DNS verification writes this column while `state` tracks mail-server provisioning, so a fully active domain can carry a populated DNS error here. Read `state`, or `GET /domains/{domain}/verification-status`, before showing this to anyone."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "Whether `POST /domains/{domain}/retry-provisioning` would do anything. True exactly when `state` is `failed`."
                                                                }
                                                            }
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "description": "Sending needs SPF and DKIM. Separate from receiving, because a customer who only relays through us must not publish an MX record.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "description": "Receiving needs MX.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "What this domain is allowed, as Mailyte records it. Every field here is always present and always a number -- there is no \"unlimited\" domain, and null is not how one would be expressed. Contrast `GET /domains/{domain}/limits`, which reports what the MAIL SERVER is enforcing and can genuinely answer \"unknown\".",
                                                            "properties": {
                                                                "storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes of mail this domain may store in total. Never null for a stored domain: the column is NOT NULL and defaults to 10 GB, so a cap always exists. Null is therefore not \"no limit\" and not \"unknown\" -- it is a value this endpoint does not produce."
                                                                },
                                                                "max_mailboxes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many mailboxes may exist on this domain. Never null for a stored domain -- the column is NOT NULL and defaults to 50. There is no \"uncapped\" domain to express, so do not read a null as permission to create without limit."
                                                                },
                                                                "mailboxes_used": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many exist now. A real count, never null and never omitted: every operation that returns a domain loads it first, precisely so a listed domain and a fetched one carry the same fields. 0 means the domain genuinely has no mailboxes."
                                                                }
                                                            }
                                                        },
                                                        "defaults": {
                                                            "type": "object",
                                                            "description": "What a NEW mailbox on this domain inherits. Nothing here describes an existing mailbox.",
                                                            "properties": {
                                                                "mailbox_storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes each new mailbox is given. Never null for a stored domain -- the column is NOT NULL and defaults to 3 GB. Null would not mean \"unlimited\"; an unlimited mailbox is not something this field can express."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/disable": {
            "post": {
                "operationId": "postDomainsDomainDisable",
                "summary": "Disable a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the domain."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The domain itself, e.g. `example.com`."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "A free-text note the customer set on the domain. Null means NONE was ever given -- the column is nullable and nothing defaults it. It is not withheld and it is not unknown."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "disabled"
                                                            ],
                                                            "description": "The one lifecycle answer. `disabled` wins over everything: a disabled domain does nothing whatever its provisioning says."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "How far this domain has got on the mail server. This is the detail behind `state`, not a second answer to it: read `state` to decide what a domain can do, and this to explain why.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail-server provisioning lifecycle, a closed set: `pending` -> `provisioning` -> `active` or `failed`; `active` -> `suspended`; any live state -> `deleting` -> `deleted`. Never null for a stored domain -- the column is NOT NULL and defaults to `pending`, so every domain has one from the moment it is created. Distinct from the published `state`, which answers what the domain can do rather than where it is on the mail server."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning last failed. Null means NONE is recorded -- nothing has failed, or the last failure was cleared. **A non-null error does not imply `state` is `failed`.** The two are written by different code paths on different lifecycles: DNS verification writes this column while `state` tracks mail-server provisioning, so a fully active domain can carry a populated DNS error here. Read `state`, or `GET /domains/{domain}/verification-status`, before showing this to anyone."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "Whether `POST /domains/{domain}/retry-provisioning` would do anything. True exactly when `state` is `failed`."
                                                                }
                                                            }
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "description": "Sending needs SPF and DKIM. Separate from receiving, because a customer who only relays through us must not publish an MX record.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "description": "Receiving needs MX.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "What this domain is allowed, as Mailyte records it. Every field here is always present and always a number -- there is no \"unlimited\" domain, and null is not how one would be expressed. Contrast `GET /domains/{domain}/limits`, which reports what the MAIL SERVER is enforcing and can genuinely answer \"unknown\".",
                                                            "properties": {
                                                                "storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes of mail this domain may store in total. Never null for a stored domain: the column is NOT NULL and defaults to 10 GB, so a cap always exists. Null is therefore not \"no limit\" and not \"unknown\" -- it is a value this endpoint does not produce."
                                                                },
                                                                "max_mailboxes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many mailboxes may exist on this domain. Never null for a stored domain -- the column is NOT NULL and defaults to 50. There is no \"uncapped\" domain to express, so do not read a null as permission to create without limit."
                                                                },
                                                                "mailboxes_used": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many exist now. A real count, never null and never omitted: every operation that returns a domain loads it first, precisely so a listed domain and a fetched one carry the same fields. 0 means the domain genuinely has no mailboxes."
                                                                }
                                                            }
                                                        },
                                                        "defaults": {
                                                            "type": "object",
                                                            "description": "What a NEW mailbox on this domain inherits. Nothing here describes an existing mailbox.",
                                                            "properties": {
                                                                "mailbox_storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes each new mailbox is given. Never null for a stored domain -- the column is NOT NULL and defaults to 3 GB. Null would not mean \"unlimited\"; an unlimited mailbox is not something this field can express."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/retry-provisioning": {
            "post": {
                "operationId": "postDomainsDomainRetryProvisioning",
                "summary": "Retry Provisioning a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the domain."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The domain itself, e.g. `example.com`."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "A free-text note the customer set on the domain. Null means NONE was ever given -- the column is nullable and nothing defaults it. It is not withheld and it is not unknown."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "disabled"
                                                            ],
                                                            "description": "The one lifecycle answer. `disabled` wins over everything: a disabled domain does nothing whatever its provisioning says."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "How far this domain has got on the mail server. This is the detail behind `state`, not a second answer to it: read `state` to decide what a domain can do, and this to explain why.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail-server provisioning lifecycle, a closed set: `pending` -> `provisioning` -> `active` or `failed`; `active` -> `suspended`; any live state -> `deleting` -> `deleted`. Never null for a stored domain -- the column is NOT NULL and defaults to `pending`, so every domain has one from the moment it is created. Distinct from the published `state`, which answers what the domain can do rather than where it is on the mail server."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning last failed. Null means NONE is recorded -- nothing has failed, or the last failure was cleared. **A non-null error does not imply `state` is `failed`.** The two are written by different code paths on different lifecycles: DNS verification writes this column while `state` tracks mail-server provisioning, so a fully active domain can carry a populated DNS error here. Read `state`, or `GET /domains/{domain}/verification-status`, before showing this to anyone."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "Whether `POST /domains/{domain}/retry-provisioning` would do anything. True exactly when `state` is `failed`."
                                                                }
                                                            }
                                                        },
                                                        "sending": {
                                                            "type": "object",
                                                            "description": "Sending needs SPF and DKIM. Separate from receiving, because a customer who only relays through us must not publish an MX record.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "receiving": {
                                                            "type": "object",
                                                            "description": "Receiving needs MX.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "requires": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "What this domain is allowed, as Mailyte records it. Every field here is always present and always a number -- there is no \"unlimited\" domain, and null is not how one would be expressed. Contrast `GET /domains/{domain}/limits`, which reports what the MAIL SERVER is enforcing and can genuinely answer \"unknown\".",
                                                            "properties": {
                                                                "storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes of mail this domain may store in total. Never null for a stored domain: the column is NOT NULL and defaults to 10 GB, so a cap always exists. Null is therefore not \"no limit\" and not \"unknown\" -- it is a value this endpoint does not produce."
                                                                },
                                                                "max_mailboxes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many mailboxes may exist on this domain. Never null for a stored domain -- the column is NOT NULL and defaults to 50. There is no \"uncapped\" domain to express, so do not read a null as permission to create without limit."
                                                                },
                                                                "mailboxes_used": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many exist now. A real count, never null and never omitted: every operation that returns a domain loads it first, precisely so a listed domain and a fetched one carry the same fields. 0 means the domain genuinely has no mailboxes."
                                                                }
                                                            }
                                                        },
                                                        "defaults": {
                                                            "type": "object",
                                                            "description": "What a NEW mailbox on this domain inherits. Nothing here describes an existing mailbox.",
                                                            "properties": {
                                                                "mailbox_storage_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes each new mailbox is given. Never null for a stored domain -- the column is NOT NULL and defaults to 3 GB. Null would not mean \"unlimited\"; an unlimited mailbox is not something this field can express."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/limits": {
            "get": {
                "operationId": "getDomainsDomainLimits",
                "summary": "Limits a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "limits"
                                                            ]
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain",
                                                                "mailbox"
                                                            ],
                                                            "description": "What these limits are about."
                                                        },
                                                        "identifier": {
                                                            "type": "string",
                                                            "description": "The domain name, or the mailbox address."
                                                        },
                                                        "sending_rate": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Outbound rate limits and what has been used against them. Null when the mail server could not be reached -- unknown, not zero.",
                                                            "properties": {
                                                                "limits": {
                                                                    "type": "object",
                                                                    "description": "Messages permitted per window. **0 means no limit** for a window; null means the ceiling is unknown. See each field -- reading those two the wrong way round has opposite consequences.",
                                                                    "properties": {
                                                                        "hourly": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages permitted per hour. **0 means NO LIMIT** for this window -- it is the mail server's own convention, not an absence of data, and a client that reads 0 as \"capped at nothing\" blocks a customer who has no cap. Null is the opposite reading: UNKNOWN. The configuration is always complete when it is returned at all -- the rate limiter substitutes a default rule for an entity it has no row for -- so a null here means it answered without its configuration and no ceiling could be read. Null is never \"no limit\"."
                                                                        },
                                                                        "daily": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages permitted per day. **0 means NO LIMIT** for this window -- it is the mail server's own convention, not an absence of data, and a client that reads 0 as \"capped at nothing\" blocks a customer who has no cap. Null is the opposite reading: UNKNOWN. The configuration is always complete when it is returned at all -- the rate limiter substitutes a default rule for an entity it has no row for -- so a null here means it answered without its configuration and no ceiling could be read. Null is never \"no limit\"."
                                                                        },
                                                                        "monthly": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages permitted per calendar month. **0 means NO LIMIT** for this window -- it is the mail server's own convention, not an absence of data, and a client that reads 0 as \"capped at nothing\" blocks a customer who has no cap. Null is the opposite reading: UNKNOWN. The configuration is always complete when it is returned at all -- the rate limiter substitutes a default rule for an entity it has no row for -- so a null here means it answered without its configuration and no ceiling could be read. Null is never \"no limit\"."
                                                                        },
                                                                        "burst": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages permitted per burst window. **0 means NO LIMIT** for this window -- it is the mail server's own convention, not an absence of data, and a client that reads 0 as \"capped at nothing\" blocks a customer who has no cap. Null is the opposite reading: UNKNOWN. The configuration is always complete when it is returned at all -- the rate limiter substitutes a default rule for an entity it has no row for -- so a null here means it answered without its configuration and no ceiling could be read. Null is never \"no limit\". Note that this ceiling is carried in the configuration but is NOT one of the windows the mail server actually enforces on a send, so it describes intent rather than what will stop a message."
                                                                        }
                                                                    }
                                                                },
                                                                "used": {
                                                                    "type": "object",
                                                                    "description": "Consumed so far in each window. Subtract from `limits` for what is left; there is deliberately no second field saying so. Null means the meter was not read, and 0 is weaker evidence than it looks -- see each field.",
                                                                    "properties": {
                                                                        "hourly": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages sent in the current hour. Null means UNKNOWN -- the meter was not read. **Treat 0 with the same caution**: when its counter store is unavailable the rate limiter substitutes zeroed counters of its own rather than failing, so 0 means \"no usage was recorded\", which is not the same as proof that nothing was sent. Do not bill, throttle or report quota exhaustion from this figure alone."
                                                                        },
                                                                        "daily": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages sent in the current day. Null means UNKNOWN -- the meter was not read. **Treat 0 with the same caution**: when its counter store is unavailable the rate limiter substitutes zeroed counters of its own rather than failing, so 0 means \"no usage was recorded\", which is not the same as proof that nothing was sent. Do not bill, throttle or report quota exhaustion from this figure alone."
                                                                        },
                                                                        "monthly": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages sent in the current calendar month. Null means UNKNOWN -- the meter was not read. **Treat 0 with the same caution**: when its counter store is unavailable the rate limiter substitutes zeroed counters of its own rather than failing, so 0 means \"no usage was recorded\", which is not the same as proof that nothing was sent. Do not bill, throttle or report quota exhaustion from this figure alone."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Stored mail. Usage and quota are two separate upstream calls, so one can be known while the other is not; this block is null only when BOTH were unreachable -- unknown, not zero.",
                                                            "properties": {
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes currently stored. Null means UNKNOWN -- the usage call failed, or the mail server holds no usage row for this entity yet. 0 means it was measured and is empty. The quota fields beside this one come from a different call and are unaffected either way."
                                                                },
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes permitted. **Null has two readings and `message_size` separates them.** When `message_size` is present the quota call succeeded and null means NO LIMIT -- storage is uncapped for this entity, with organization-level inheritance already applied upstream, so it is a settled answer and not \"ask the parent\". When `message_size` is also null the quota call itself failed and this is UNKNOWN. Note this is the OPPOSITE convention from `sending_rate.limits`, where no limit is 0; the two figures come from two different services."
                                                                },
                                                                "messages": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages stored. Null means UNKNOWN, on exactly the same terms as `used_bytes` -- it is read by the same call. 0 means measured and empty."
                                                                }
                                                            }
                                                        },
                                                        "message_size": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Per-message ceilings enforced at delivery. Null when the mail server could not be reached -- unknown, not zero. Because this block is present only when the quota call succeeded, it also tells you how to read `storage.quota_bytes`.",
                                                            "properties": {
                                                                "max_message_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. Null means NO LIMIT -- no ceiling is configured for this entity or inherited from its organization. This block exists only when the quota call succeeded, so null here is never \"unknown\"."
                                                                },
                                                                "max_attachment_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. Null means NO LIMIT, on the same terms as `max_message_bytes`: settled, not unknown."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/limits/{email}": {
            "get": {
                "operationId": "getDomainsDomainLimitsEmail",
                "summary": "Retrieve a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "domains:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "email",
                        "in": "path",
                        "required": true,
                        "description": "The email identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "limits"
                                                            ]
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain",
                                                                "mailbox"
                                                            ],
                                                            "description": "What these limits are about."
                                                        },
                                                        "identifier": {
                                                            "type": "string",
                                                            "description": "The domain name, or the mailbox address."
                                                        },
                                                        "sending_rate": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Outbound rate limits and what has been used against them. Null when the mail server could not be reached -- unknown, not zero.",
                                                            "properties": {
                                                                "limits": {
                                                                    "type": "object",
                                                                    "description": "Messages permitted per window. **0 means no limit** for a window; null means the ceiling is unknown. See each field -- reading those two the wrong way round has opposite consequences.",
                                                                    "properties": {
                                                                        "hourly": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages permitted per hour. **0 means NO LIMIT** for this window -- it is the mail server's own convention, not an absence of data, and a client that reads 0 as \"capped at nothing\" blocks a customer who has no cap. Null is the opposite reading: UNKNOWN. The configuration is always complete when it is returned at all -- the rate limiter substitutes a default rule for an entity it has no row for -- so a null here means it answered without its configuration and no ceiling could be read. Null is never \"no limit\"."
                                                                        },
                                                                        "daily": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages permitted per day. **0 means NO LIMIT** for this window -- it is the mail server's own convention, not an absence of data, and a client that reads 0 as \"capped at nothing\" blocks a customer who has no cap. Null is the opposite reading: UNKNOWN. The configuration is always complete when it is returned at all -- the rate limiter substitutes a default rule for an entity it has no row for -- so a null here means it answered without its configuration and no ceiling could be read. Null is never \"no limit\"."
                                                                        },
                                                                        "monthly": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages permitted per calendar month. **0 means NO LIMIT** for this window -- it is the mail server's own convention, not an absence of data, and a client that reads 0 as \"capped at nothing\" blocks a customer who has no cap. Null is the opposite reading: UNKNOWN. The configuration is always complete when it is returned at all -- the rate limiter substitutes a default rule for an entity it has no row for -- so a null here means it answered without its configuration and no ceiling could be read. Null is never \"no limit\"."
                                                                        },
                                                                        "burst": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages permitted per burst window. **0 means NO LIMIT** for this window -- it is the mail server's own convention, not an absence of data, and a client that reads 0 as \"capped at nothing\" blocks a customer who has no cap. Null is the opposite reading: UNKNOWN. The configuration is always complete when it is returned at all -- the rate limiter substitutes a default rule for an entity it has no row for -- so a null here means it answered without its configuration and no ceiling could be read. Null is never \"no limit\". Note that this ceiling is carried in the configuration but is NOT one of the windows the mail server actually enforces on a send, so it describes intent rather than what will stop a message."
                                                                        }
                                                                    }
                                                                },
                                                                "used": {
                                                                    "type": "object",
                                                                    "description": "Consumed so far in each window. Subtract from `limits` for what is left; there is deliberately no second field saying so. Null means the meter was not read, and 0 is weaker evidence than it looks -- see each field.",
                                                                    "properties": {
                                                                        "hourly": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages sent in the current hour. Null means UNKNOWN -- the meter was not read. **Treat 0 with the same caution**: when its counter store is unavailable the rate limiter substitutes zeroed counters of its own rather than failing, so 0 means \"no usage was recorded\", which is not the same as proof that nothing was sent. Do not bill, throttle or report quota exhaustion from this figure alone."
                                                                        },
                                                                        "daily": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages sent in the current day. Null means UNKNOWN -- the meter was not read. **Treat 0 with the same caution**: when its counter store is unavailable the rate limiter substitutes zeroed counters of its own rather than failing, so 0 means \"no usage was recorded\", which is not the same as proof that nothing was sent. Do not bill, throttle or report quota exhaustion from this figure alone."
                                                                        },
                                                                        "monthly": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Messages sent in the current calendar month. Null means UNKNOWN -- the meter was not read. **Treat 0 with the same caution**: when its counter store is unavailable the rate limiter substitutes zeroed counters of its own rather than failing, so 0 means \"no usage was recorded\", which is not the same as proof that nothing was sent. Do not bill, throttle or report quota exhaustion from this figure alone."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Stored mail. Usage and quota are two separate upstream calls, so one can be known while the other is not; this block is null only when BOTH were unreachable -- unknown, not zero.",
                                                            "properties": {
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes currently stored. Null means UNKNOWN -- the usage call failed, or the mail server holds no usage row for this entity yet. 0 means it was measured and is empty. The quota fields beside this one come from a different call and are unaffected either way."
                                                                },
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes permitted. **Null has two readings and `message_size` separates them.** When `message_size` is present the quota call succeeded and null means NO LIMIT -- storage is uncapped for this entity, with organization-level inheritance already applied upstream, so it is a settled answer and not \"ask the parent\". When `message_size` is also null the quota call itself failed and this is UNKNOWN. Note this is the OPPOSITE convention from `sending_rate.limits`, where no limit is 0; the two figures come from two different services."
                                                                },
                                                                "messages": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages stored. Null means UNKNOWN, on exactly the same terms as `used_bytes` -- it is read by the same call. 0 means measured and empty."
                                                                }
                                                            }
                                                        },
                                                        "message_size": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Per-message ceilings enforced at delivery. Null when the mail server could not be reached -- unknown, not zero. Because this block is present only when the quota call succeeded, it also tells you how to read `storage.quota_bytes`.",
                                                            "properties": {
                                                                "max_message_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. Null means NO LIMIT -- no ceiling is configured for this entity or inherited from its organization. This block exists only when the quota call succeeded, so null here is never \"unknown\"."
                                                                },
                                                                "max_attachment_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. Null means NO LIMIT, on the same terms as `max_message_bytes`: settled, not unknown."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/analytics": {
            "get": {
                "operationId": "getDomainsDomainAnalytics",
                "summary": "Analytics a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain_analytics"
                                                            ]
                                                        },
                                                        "domain_id": {
                                                            "type": "string"
                                                        },
                                                        "period": {
                                                            "type": "object",
                                                            "description": "Defaults to the last 30 days. Both bounds are inclusive.",
                                                            "properties": {
                                                                "start_date": {
                                                                    "type": "string",
                                                                    "format": "date"
                                                                },
                                                                "end_date": {
                                                                    "type": "string",
                                                                    "format": "date"
                                                                }
                                                            }
                                                        },
                                                        "series": {
                                                            "type": "object",
                                                            "properties": {
                                                                "emails_sent": {
                                                                    "type": "array",
                                                                    "description": "Messages accepted for delivery. One point per day in the window, including days with no data.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "date": {
                                                                                "type": "string",
                                                                                "format": "date"
                                                                            },
                                                                            "value": {
                                                                                "type": "number",
                                                                                "nullable": true,
                                                                                "description": "A count, never null: every day in the window is present, and a day with no recorded events is written as 0 rather than left out. Read that 0 as \"nothing was recorded\", not as proof that nothing happened."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "emails_received": {
                                                                    "type": "array",
                                                                    "description": "Messages delivered to this domain. One point per day in the window, including days with no data.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "date": {
                                                                                "type": "string",
                                                                                "format": "date"
                                                                            },
                                                                            "value": {
                                                                                "type": "number",
                                                                                "nullable": true,
                                                                                "description": "A count, never null: every day in the window is present, and a day with no recorded events is written as 0 rather than left out. Read that 0 as \"nothing was recorded\", not as proof that nothing happened."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "delivery_rate": {
                                                                    "type": "array",
                                                                    "description": "Delivered as a share of sent, per day. One point per day in the window, including days with no data.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "date": {
                                                                                "type": "string",
                                                                                "format": "date"
                                                                            },
                                                                            "value": {
                                                                                "type": "number",
                                                                                "nullable": true,
                                                                                "description": "A percentage. Null on a day with no sends -- there is no rate without a denominator."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "bounce_rate": {
                                                                    "type": "array",
                                                                    "description": "Bounced as a share of sent, per day. One point per day in the window, including days with no data.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "date": {
                                                                                "type": "string",
                                                                                "format": "date"
                                                                            },
                                                                            "value": {
                                                                                "type": "number",
                                                                                "nullable": true,
                                                                                "description": "A percentage. Null on a day with no sends."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "spam_complaints": {
                                                                    "type": "array",
                                                                    "description": "Spam reports and delivery complaints. One point per day in the window, including days with no data.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "date": {
                                                                                "type": "string",
                                                                                "format": "date"
                                                                            },
                                                                            "value": {
                                                                                "type": "number",
                                                                                "nullable": true,
                                                                                "description": "A count, never null: every day in the window is present, and a day with no recorded events is written as 0 rather than left out. Read that 0 as \"nothing was recorded\", not as proof that nothing happened."
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/health": {
            "get": {
                "operationId": "getDomainsDomainHealth",
                "summary": "Health a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain_health"
                                                            ]
                                                        },
                                                        "domain_id": {
                                                            "type": "string"
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "enum": [
                                                                "good",
                                                                "warning",
                                                                "critical"
                                                            ],
                                                            "description": "Banded from `score`: good at 90 and above, warning at 60, critical below it."
                                                        },
                                                        "score": {
                                                            "type": "integer",
                                                            "description": "0-100."
                                                        },
                                                        "issues": {
                                                            "type": "array",
                                                            "description": "Every problem found, each with its own fix. Empty when there are none.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "issue": {
                                                                        "type": "string"
                                                                    },
                                                                    "recommendation": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "What to do about this issue. Null means NONE is attached to this particular problem -- it is not withheld and it is not unknown. In practice it is never null today: every branch that raises an issue writes its advice in the same breath. It is nullable so that the day one does not, the problem is still reported rather than dropped, and no issue ever inherits the advice meant for another."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "metrics": {
                                                            "type": "object",
                                                            "description": "The last 30 days.",
                                                            "properties": {
                                                                "emails_sent": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages accepted for delivery in the last 30 days. Never null -- it is read from the daily rollup, which answers 0 for a window it holds no rows for. **0 therefore means \"no events are recorded\", not \"nothing was sent\"**, and the rates beside it are null for exactly that reason: with no denominator there is no rate. A domain that has sent mail but whose events never reached the rollup looks identical to one that has sent none."
                                                                },
                                                                "delivery_rate": {
                                                                    "type": "number",
                                                                    "nullable": true,
                                                                    "description": "Percentage of sent mail confirmed delivered. Null means there was no traffic in the window to compute a rate from -- not 0%, and emphatically not 100%."
                                                                },
                                                                "bounce_rate": {
                                                                    "type": "number",
                                                                    "nullable": true,
                                                                    "description": "Percentage of sent mail that bounced. Null means there was no traffic in the window to compute a rate from -- not 0%, and emphatically not 100%."
                                                                },
                                                                "spam_rate": {
                                                                    "type": "number",
                                                                    "nullable": true,
                                                                    "description": "Percentage of sent mail reported as spam. Null means there was no traffic in the window to compute a rate from -- not 0%, and emphatically not 100%."
                                                                }
                                                            }
                                                        },
                                                        "checked_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When DNS was last resolved for this domain. Null when it never has been."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/domains/{domain}/stats": {
            "get": {
                "operationId": "getDomainsDomainStats",
                "summary": "Stats a domain",
                "tags": [
                    "Domains"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "domain",
                        "in": "path",
                        "required": true,
                        "description": "The domain id, or the domain name itself.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain_usage"
                                                            ]
                                                        },
                                                        "domain_id": {
                                                            "type": "string"
                                                        },
                                                        "mailboxes": {
                                                            "type": "object",
                                                            "description": "Counted from the mailbox rows themselves at request time, not from a rollup, so these two are never stale and never unknown.",
                                                            "properties": {
                                                                "total": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Mailboxes on this domain. A live `COUNT`, so it is never null and 0 means the domain genuinely has none."
                                                                },
                                                                "active": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Of those, how many are active. A live `COUNT`, never null; 0 means none are active, which on a domain with mailboxes is a real finding rather than a missing reading."
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "properties": {
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes, summed across this domain's mailboxes. Never null: it is a `SUM` over rows this API owns, and a domain with no mailboxes sums to a genuine 0."
                                                                },
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. The same value as `limits.storage_bytes` on the domain, and never null for the same reason -- the column is NOT NULL. **0 means no quota is enforced**; that is how \"unlimited\" is said here, not null."
                                                                }
                                                            }
                                                        },
                                                        "today": {
                                                            "type": "object",
                                                            "description": "Since midnight UTC.",
                                                            "properties": {
                                                                "emails_sent": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages accepted for delivery since midnight UTC. Never null -- it is read from the daily rollup, which answers 0 for a day it holds no rows for. **So 0 means \"the rollup records nothing today\", which is not the same as proof that nothing was sent**: a rollup that has not run yet reports the same 0. Treat it as a lower bound, and do not bill from it."
                                                                },
                                                                "emails_received": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages delivered to this domain since midnight UTC. Never null, and 0 carries the same caveat as `emails_sent`: it is the absence of recorded events, not measured silence."
                                                                },
                                                                "delivery_rate": {
                                                                    "type": "number",
                                                                    "nullable": true,
                                                                    "description": "Percentage. Null when nothing was sent today -- there is no rate without a denominator."
                                                                },
                                                                "bounce_rate": {
                                                                    "type": "number",
                                                                    "nullable": true,
                                                                    "description": "Percentage. Null when nothing was sent today."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts": {
            "get": {
                "operationId": "getEmailAccounts",
                "summary": "List email accounts",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "mailbox"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Unique identifier for the mailbox."
                                                                    },
                                                                    "address": {
                                                                        "type": "string",
                                                                        "description": "The full email address. This *is* the mailbox publicly: there is no separate `username`, because the local part is already in here."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Display name, as it appears to a recipient. null when none was set."
                                                                    },
                                                                    "domain_id": {
                                                                        "type": "string",
                                                                        "description": "The domain this mailbox belongs to. Retrieve it with `GET /api/v1/domains/{domain}`."
                                                                    },
                                                                    "type": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "mail",
                                                                            "smtp",
                                                                            "both"
                                                                        ],
                                                                        "description": "What the mailbox was created as, and what you can filter the list by. Recorded rather than enforced: nothing in the product currently branches on it, so it does not by itself restrict what the mailbox can do."
                                                                    },
                                                                    "state": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "active",
                                                                            "provisioning",
                                                                            "failed",
                                                                            "suspended",
                                                                            "deleting"
                                                                        ],
                                                                        "description": "The one lifecycle answer, ordered by what stops you first: `deleting` outranks everything, then `suspended` (a business decision, whatever the mail server thinks), then what provisioning says. Only an `active` mailbox sends and receives."
                                                                    },
                                                                    "provisioning": {
                                                                        "type": "object",
                                                                        "description": "What the mail server has done with this mailbox. Creation is asynchronous, so a mailbox exists here before it exists there.",
                                                                        "properties": {
                                                                            "state": {
                                                                                "type": "string",
                                                                                "enum": [
                                                                                    "pending",
                                                                                    "provisioning",
                                                                                    "active",
                                                                                    "failed",
                                                                                    "suspended",
                                                                                    "deleting",
                                                                                    "deleted"
                                                                                ],
                                                                                "description": "The mail server's own lifecycle value, as stored. **Never null**, and not nullable: `email_accounts.provisioning_state` is NOT NULL, defaults to `pending`, and creation writes `pending` explicitly before the row is inserted \u2014 so a mailbox always carries one. It is read from OUR database, not fetched from the mail server, so unlike `storage.used_bytes` it never goes unknown when that host is unreachable; a mail server we cannot reach leaves this value STALE, not absent. Every value the product writes today is in the set above, but rows that predate the column can still hold a spelling that is not \u2014 `provisioned` survives in real data \u2014 so branch on the top-level `state`, which normalises whatever is stored into a set that really is closed."
                                                                            },
                                                                            "error": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "Why provisioning failed, in the mail server's words. null unless `state` is `failed`."
                                                                            },
                                                                            "retryable": {
                                                                                "type": "boolean",
                                                                                "description": "True only while `state` is `failed`, which is the only state `POST /retry-provisioning` accepts."
                                                                            }
                                                                        }
                                                                    },
                                                                    "storage": {
                                                                        "type": "object",
                                                                        "description": "Bytes, both of them. Never a pre-formatted \"3 GB\", which cannot be computed with.",
                                                                        "properties": {
                                                                            "quota_bytes": {
                                                                                "type": "integer",
                                                                                "description": "Bytes. The ceiling set for this mailbox. **Never null**, and not nullable \u2014 read the contrast with `used_bytes` below, because the two figures in this object have very different reliability. The quota is OUR number, held in MySQL in a NOT NULL column, and a mailbox created without an explicit quota is given one (1 GB), so there is always an answer and it never depends on the mail server being reachable. `used_bytes` is the mail server's number and can be unknown. A null here would mean the mailbox has no ceiling, which is not a state this product can be in."
                                                                            },
                                                                            "used_bytes": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "Bytes. **null means we could not read the figure, not that the mailbox is empty** \u2014 usage is measured on the mail server and is null whenever the mailbox does not exist there yet, so there has been nothing to measure. Treat null as \"unknown\" and show it as such: a customer told they have used nothing, when in truth we could not ask, will discover the difference the day they hit the quota. A mailbox that IS provisioned but whose storage has never been synced currently reads 0 rather than null; the column cannot yet express the difference."
                                                                            }
                                                                        }
                                                                    },
                                                                    "send_limits": {
                                                                        "type": "object",
                                                                        "description": "Per-mailbox sending overrides.",
                                                                        "properties": {
                                                                            "daily": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "Messages per day. **null means no override, not unlimited** \u2014 the organization's plan limit applies instead. A 0 would mean \"may not send\"."
                                                                            },
                                                                            "hourly": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "Messages per hour. null means no override, exactly as `daily`."
                                                                            }
                                                                        }
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    },
                                                                    "updated_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postEmailAccounts",
                "summary": "Create a mailbox",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the mailbox."
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "description": "The full email address. This *is* the mailbox publicly: there is no separate `username`, because the local part is already in here."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Display name, as it appears to a recipient. null when none was set."
                                                        },
                                                        "domain_id": {
                                                            "type": "string",
                                                            "description": "The domain this mailbox belongs to. Retrieve it with `GET /api/v1/domains/{domain}`."
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mail",
                                                                "smtp",
                                                                "both"
                                                            ],
                                                            "description": "What the mailbox was created as, and what you can filter the list by. Recorded rather than enforced: nothing in the product currently branches on it, so it does not by itself restrict what the mailbox can do."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "suspended",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first: `deleting` outranks everything, then `suspended` (a business decision, whatever the mail server thinks), then what provisioning says. Only an `active` mailbox sends and receives."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "What the mail server has done with this mailbox. Creation is asynchronous, so a mailbox exists here before it exists there.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail server's own lifecycle value, as stored. **Never null**, and not nullable: `email_accounts.provisioning_state` is NOT NULL, defaults to `pending`, and creation writes `pending` explicitly before the row is inserted \u2014 so a mailbox always carries one. It is read from OUR database, not fetched from the mail server, so unlike `storage.used_bytes` it never goes unknown when that host is unreachable; a mail server we cannot reach leaves this value STALE, not absent. Every value the product writes today is in the set above, but rows that predate the column can still hold a spelling that is not \u2014 `provisioned` survives in real data \u2014 so branch on the top-level `state`, which normalises whatever is stored into a set that really is closed."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning failed, in the mail server's words. null unless `state` is `failed`."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "True only while `state` is `failed`, which is the only state `POST /retry-provisioning` accepts."
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "description": "Bytes, both of them. Never a pre-formatted \"3 GB\", which cannot be computed with.",
                                                            "properties": {
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "description": "Bytes. The ceiling set for this mailbox. **Never null**, and not nullable \u2014 read the contrast with `used_bytes` below, because the two figures in this object have very different reliability. The quota is OUR number, held in MySQL in a NOT NULL column, and a mailbox created without an explicit quota is given one (1 GB), so there is always an answer and it never depends on the mail server being reachable. `used_bytes` is the mail server's number and can be unknown. A null here would mean the mailbox has no ceiling, which is not a state this product can be in."
                                                                },
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. **null means we could not read the figure, not that the mailbox is empty** \u2014 usage is measured on the mail server and is null whenever the mailbox does not exist there yet, so there has been nothing to measure. Treat null as \"unknown\" and show it as such: a customer told they have used nothing, when in truth we could not ask, will discover the difference the day they hit the quota. A mailbox that IS provisioned but whose storage has never been synced currently reads 0 rather than null; the column cannot yet express the difference."
                                                                }
                                                            }
                                                        },
                                                        "send_limits": {
                                                            "type": "object",
                                                            "description": "Per-mailbox sending overrides.",
                                                            "properties": {
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per day. **null means no override, not unlimited** \u2014 the organization's plan limit applies instead. A 0 would mean \"may not send\"."
                                                                },
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per hour. null means no override, exactly as `daily`."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Creates a real mailbox \u2014 IMAP, SMTP and webmail \u2014 on one of your domains.\n\nThe domain must exist, but it does **not** need to be verified: you will usually want\nmailboxes in place before you cut MX over, not after. Provisioning happens on the mail\nserver and is asynchronous; a mailbox appears with a provisioning status and becomes\nusable when that completes.\n\nPasswords must be at least 12 characters. If you set a forced password change, note it\ngoverns webmail and the mobile apps only \u2014 IMAP and SMTP clients cannot present a\nchange-password prompt, so they keep working with the old password until it is changed\nelsewhere."
            }
        },
        "/api/v1/email-accounts/bulk-update": {
            "post": {
                "operationId": "postEmailAccountsBulkUpdate",
                "summary": "Bulk Update (email account)",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox_bulk_result"
                                                            ]
                                                        },
                                                        "updated": {
                                                            "type": "integer",
                                                            "description": "How many mailboxes were changed."
                                                        },
                                                        "failed": {
                                                            "type": "integer",
                                                            "description": "How many were not. **A bulk update is not atomic**: a 200 with `failed` above zero means part of your batch did not happen, so check this rather than the status code."
                                                        },
                                                        "errors": {
                                                            "type": "array",
                                                            "description": "One entry per failure, and the only place the failures are named. Empty when `failed` is 0.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "mailbox_id": {
                                                                        "type": "string",
                                                                        "description": "Which mailbox failed. **Never null, and never a mailbox we could not identify** \u2014 it is the id YOU sent in `account_ids`, copied into the failure row before the mailbox is looked up, so a row that failed *because the mailbox could not be loaded* still names it. That is worth stating because the obvious reading of a null here would be \"it failed before we resolved an id\", and that case does not exist: every id in the request has already been checked to exist before any of the batch runs, so a failure is the action failing, not the id being wrong. Pair it back to your own request to find out which item to retry."
                                                                    },
                                                                    "message": {
                                                                        "type": "string",
                                                                        "description": "Why that mailbox was not updated, in the underlying exception's words. **Never null**: a row only exists here because something threw, and both of its fields are always written together. For a human reading a log \u2014 do not match on the text or parse it, it is not a stable identifier and this API publishes no error code for a partial bulk failure."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{email_account}": {
            "get": {
                "operationId": "getEmailAccountsEmailAccount",
                "summary": "Retrieve a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "email_account",
                        "in": "path",
                        "required": true,
                        "description": "The email account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the mailbox."
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "description": "The full email address. This *is* the mailbox publicly: there is no separate `username`, because the local part is already in here."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Display name, as it appears to a recipient. null when none was set."
                                                        },
                                                        "domain_id": {
                                                            "type": "string",
                                                            "description": "The domain this mailbox belongs to. Retrieve it with `GET /api/v1/domains/{domain}`."
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mail",
                                                                "smtp",
                                                                "both"
                                                            ],
                                                            "description": "What the mailbox was created as, and what you can filter the list by. Recorded rather than enforced: nothing in the product currently branches on it, so it does not by itself restrict what the mailbox can do."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "suspended",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first: `deleting` outranks everything, then `suspended` (a business decision, whatever the mail server thinks), then what provisioning says. Only an `active` mailbox sends and receives."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "What the mail server has done with this mailbox. Creation is asynchronous, so a mailbox exists here before it exists there.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail server's own lifecycle value, as stored. **Never null**, and not nullable: `email_accounts.provisioning_state` is NOT NULL, defaults to `pending`, and creation writes `pending` explicitly before the row is inserted \u2014 so a mailbox always carries one. It is read from OUR database, not fetched from the mail server, so unlike `storage.used_bytes` it never goes unknown when that host is unreachable; a mail server we cannot reach leaves this value STALE, not absent. Every value the product writes today is in the set above, but rows that predate the column can still hold a spelling that is not \u2014 `provisioned` survives in real data \u2014 so branch on the top-level `state`, which normalises whatever is stored into a set that really is closed."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning failed, in the mail server's words. null unless `state` is `failed`."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "True only while `state` is `failed`, which is the only state `POST /retry-provisioning` accepts."
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "description": "Bytes, both of them. Never a pre-formatted \"3 GB\", which cannot be computed with.",
                                                            "properties": {
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "description": "Bytes. The ceiling set for this mailbox. **Never null**, and not nullable \u2014 read the contrast with `used_bytes` below, because the two figures in this object have very different reliability. The quota is OUR number, held in MySQL in a NOT NULL column, and a mailbox created without an explicit quota is given one (1 GB), so there is always an answer and it never depends on the mail server being reachable. `used_bytes` is the mail server's number and can be unknown. A null here would mean the mailbox has no ceiling, which is not a state this product can be in."
                                                                },
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. **null means we could not read the figure, not that the mailbox is empty** \u2014 usage is measured on the mail server and is null whenever the mailbox does not exist there yet, so there has been nothing to measure. Treat null as \"unknown\" and show it as such: a customer told they have used nothing, when in truth we could not ask, will discover the difference the day they hit the quota. A mailbox that IS provisioned but whose storage has never been synced currently reads 0 rather than null; the column cannot yet express the difference."
                                                                }
                                                            }
                                                        },
                                                        "send_limits": {
                                                            "type": "object",
                                                            "description": "Per-mailbox sending overrides.",
                                                            "properties": {
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per day. **null means no override, not unlimited** \u2014 the organization's plan limit applies instead. A 0 would mean \"may not send\"."
                                                                },
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per hour. null means no override, exactly as `daily`."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "operationId": "putEmailAccountsEmailAccount",
                "summary": "Update a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "email_account",
                        "in": "path",
                        "required": true,
                        "description": "The email account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the mailbox."
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "description": "The full email address. This *is* the mailbox publicly: there is no separate `username`, because the local part is already in here."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Display name, as it appears to a recipient. null when none was set."
                                                        },
                                                        "domain_id": {
                                                            "type": "string",
                                                            "description": "The domain this mailbox belongs to. Retrieve it with `GET /api/v1/domains/{domain}`."
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mail",
                                                                "smtp",
                                                                "both"
                                                            ],
                                                            "description": "What the mailbox was created as, and what you can filter the list by. Recorded rather than enforced: nothing in the product currently branches on it, so it does not by itself restrict what the mailbox can do."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "suspended",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first: `deleting` outranks everything, then `suspended` (a business decision, whatever the mail server thinks), then what provisioning says. Only an `active` mailbox sends and receives."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "What the mail server has done with this mailbox. Creation is asynchronous, so a mailbox exists here before it exists there.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail server's own lifecycle value, as stored. **Never null**, and not nullable: `email_accounts.provisioning_state` is NOT NULL, defaults to `pending`, and creation writes `pending` explicitly before the row is inserted \u2014 so a mailbox always carries one. It is read from OUR database, not fetched from the mail server, so unlike `storage.used_bytes` it never goes unknown when that host is unreachable; a mail server we cannot reach leaves this value STALE, not absent. Every value the product writes today is in the set above, but rows that predate the column can still hold a spelling that is not \u2014 `provisioned` survives in real data \u2014 so branch on the top-level `state`, which normalises whatever is stored into a set that really is closed."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning failed, in the mail server's words. null unless `state` is `failed`."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "True only while `state` is `failed`, which is the only state `POST /retry-provisioning` accepts."
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "description": "Bytes, both of them. Never a pre-formatted \"3 GB\", which cannot be computed with.",
                                                            "properties": {
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "description": "Bytes. The ceiling set for this mailbox. **Never null**, and not nullable \u2014 read the contrast with `used_bytes` below, because the two figures in this object have very different reliability. The quota is OUR number, held in MySQL in a NOT NULL column, and a mailbox created without an explicit quota is given one (1 GB), so there is always an answer and it never depends on the mail server being reachable. `used_bytes` is the mail server's number and can be unknown. A null here would mean the mailbox has no ceiling, which is not a state this product can be in."
                                                                },
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. **null means we could not read the figure, not that the mailbox is empty** \u2014 usage is measured on the mail server and is null whenever the mailbox does not exist there yet, so there has been nothing to measure. Treat null as \"unknown\" and show it as such: a customer told they have used nothing, when in truth we could not ask, will discover the difference the day they hit the quota. A mailbox that IS provisioned but whose storage has never been synced currently reads 0 rather than null; the column cannot yet express the difference."
                                                                }
                                                            }
                                                        },
                                                        "send_limits": {
                                                            "type": "object",
                                                            "description": "Per-mailbox sending overrides.",
                                                            "properties": {
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per day. **null means no override, not unlimited** \u2014 the organization's plan limit applies instead. A 0 would mean \"may not send\"."
                                                                },
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per hour. null means no override, exactly as `daily`."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "operationId": "patchEmailAccountsEmailAccount",
                "summary": "Update a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "email_account",
                        "in": "path",
                        "required": true,
                        "description": "The email account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the mailbox."
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "description": "The full email address. This *is* the mailbox publicly: there is no separate `username`, because the local part is already in here."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Display name, as it appears to a recipient. null when none was set."
                                                        },
                                                        "domain_id": {
                                                            "type": "string",
                                                            "description": "The domain this mailbox belongs to. Retrieve it with `GET /api/v1/domains/{domain}`."
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mail",
                                                                "smtp",
                                                                "both"
                                                            ],
                                                            "description": "What the mailbox was created as, and what you can filter the list by. Recorded rather than enforced: nothing in the product currently branches on it, so it does not by itself restrict what the mailbox can do."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "suspended",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first: `deleting` outranks everything, then `suspended` (a business decision, whatever the mail server thinks), then what provisioning says. Only an `active` mailbox sends and receives."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "What the mail server has done with this mailbox. Creation is asynchronous, so a mailbox exists here before it exists there.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail server's own lifecycle value, as stored. **Never null**, and not nullable: `email_accounts.provisioning_state` is NOT NULL, defaults to `pending`, and creation writes `pending` explicitly before the row is inserted \u2014 so a mailbox always carries one. It is read from OUR database, not fetched from the mail server, so unlike `storage.used_bytes` it never goes unknown when that host is unreachable; a mail server we cannot reach leaves this value STALE, not absent. Every value the product writes today is in the set above, but rows that predate the column can still hold a spelling that is not \u2014 `provisioned` survives in real data \u2014 so branch on the top-level `state`, which normalises whatever is stored into a set that really is closed."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning failed, in the mail server's words. null unless `state` is `failed`."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "True only while `state` is `failed`, which is the only state `POST /retry-provisioning` accepts."
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "description": "Bytes, both of them. Never a pre-formatted \"3 GB\", which cannot be computed with.",
                                                            "properties": {
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "description": "Bytes. The ceiling set for this mailbox. **Never null**, and not nullable \u2014 read the contrast with `used_bytes` below, because the two figures in this object have very different reliability. The quota is OUR number, held in MySQL in a NOT NULL column, and a mailbox created without an explicit quota is given one (1 GB), so there is always an answer and it never depends on the mail server being reachable. `used_bytes` is the mail server's number and can be unknown. A null here would mean the mailbox has no ceiling, which is not a state this product can be in."
                                                                },
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. **null means we could not read the figure, not that the mailbox is empty** \u2014 usage is measured on the mail server and is null whenever the mailbox does not exist there yet, so there has been nothing to measure. Treat null as \"unknown\" and show it as such: a customer told they have used nothing, when in truth we could not ask, will discover the difference the day they hit the quota. A mailbox that IS provisioned but whose storage has never been synced currently reads 0 rather than null; the column cannot yet express the difference."
                                                                }
                                                            }
                                                        },
                                                        "send_limits": {
                                                            "type": "object",
                                                            "description": "Per-mailbox sending overrides.",
                                                            "properties": {
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per day. **null means no override, not unlimited** \u2014 the organization's plan limit applies instead. A 0 would mean \"may not send\"."
                                                                },
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per hour. null means no override, exactly as `daily`."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteEmailAccountsEmailAccount",
                "summary": "Delete a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "email_account",
                        "in": "path",
                        "required": true,
                        "description": "The email account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content; `message` confirms the deletion. A mailbox that exists on the mail server is deprovisioned asynchronously, so it reads `deleting` for a short while before it is gone. Deleting a mailbox deletes the mail in it, and cannot be undone."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{account}/overview": {
            "get": {
                "operationId": "getEmailAccountsAccountOverview",
                "summary": "Overview a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the mailbox."
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "description": "The full email address. This *is* the mailbox publicly: there is no separate `username`, because the local part is already in here."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Display name, as it appears to a recipient. null when none was set."
                                                        },
                                                        "domain_id": {
                                                            "type": "string",
                                                            "description": "The domain this mailbox belongs to. Retrieve it with `GET /api/v1/domains/{domain}`."
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mail",
                                                                "smtp",
                                                                "both"
                                                            ],
                                                            "description": "What the mailbox was created as, and what you can filter the list by. Recorded rather than enforced: nothing in the product currently branches on it, so it does not by itself restrict what the mailbox can do."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "suspended",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first: `deleting` outranks everything, then `suspended` (a business decision, whatever the mail server thinks), then what provisioning says. Only an `active` mailbox sends and receives."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "What the mail server has done with this mailbox. Creation is asynchronous, so a mailbox exists here before it exists there.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail server's own lifecycle value, as stored. **Never null**, and not nullable: `email_accounts.provisioning_state` is NOT NULL, defaults to `pending`, and creation writes `pending` explicitly before the row is inserted \u2014 so a mailbox always carries one. It is read from OUR database, not fetched from the mail server, so unlike `storage.used_bytes` it never goes unknown when that host is unreachable; a mail server we cannot reach leaves this value STALE, not absent. Every value the product writes today is in the set above, but rows that predate the column can still hold a spelling that is not \u2014 `provisioned` survives in real data \u2014 so branch on the top-level `state`, which normalises whatever is stored into a set that really is closed."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning failed, in the mail server's words. null unless `state` is `failed`."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "True only while `state` is `failed`, which is the only state `POST /retry-provisioning` accepts."
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "description": "Bytes, both of them. Never a pre-formatted \"3 GB\", which cannot be computed with.",
                                                            "properties": {
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "description": "Bytes. The ceiling set for this mailbox. **Never null**, and not nullable \u2014 read the contrast with `used_bytes` below, because the two figures in this object have very different reliability. The quota is OUR number, held in MySQL in a NOT NULL column, and a mailbox created without an explicit quota is given one (1 GB), so there is always an answer and it never depends on the mail server being reachable. `used_bytes` is the mail server's number and can be unknown. A null here would mean the mailbox has no ceiling, which is not a state this product can be in."
                                                                },
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. **null means we could not read the figure, not that the mailbox is empty** \u2014 usage is measured on the mail server and is null whenever the mailbox does not exist there yet, so there has been nothing to measure. Treat null as \"unknown\" and show it as such: a customer told they have used nothing, when in truth we could not ask, will discover the difference the day they hit the quota. A mailbox that IS provisioned but whose storage has never been synced currently reads 0 rather than null; the column cannot yet express the difference."
                                                                }
                                                            }
                                                        },
                                                        "send_limits": {
                                                            "type": "object",
                                                            "description": "Per-mailbox sending overrides.",
                                                            "properties": {
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per day. **null means no override, not unlimited** \u2014 the organization's plan limit applies instead. A 0 would mean \"may not send\"."
                                                                },
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per hour. null means no override, exactly as `daily`."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{account}/stats": {
            "get": {
                "operationId": "getEmailAccountsAccountStats",
                "summary": "Stats a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox_stats"
                                                            ]
                                                        },
                                                        "mailbox_id": {
                                                            "type": "string",
                                                            "description": "The mailbox these counters describe. Retrieve it with `GET /api/v1/email-accounts/{email_account}`."
                                                        },
                                                        "messages": {
                                                            "type": "object",
                                                            "description": "Five independent answers about one set of messages. **`total` is not `sent` + `received`**: a message can be counted in both `unread` and `starred`, and `total` counts rows. Do not expect these to add up.",
                                                            "properties": {
                                                                "total": {
                                                                    "type": "integer"
                                                                },
                                                                "sent": {
                                                                    "type": "integer"
                                                                },
                                                                "received": {
                                                                    "type": "integer"
                                                                },
                                                                "unread": {
                                                                    "type": "integer"
                                                                },
                                                                "starred": {
                                                                    "type": "integer"
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "description": "Bytes, and the same two figures as `storage` on the mailbox object. The percentage this endpoint used to publish is gone: it is `used / quota`, which you can compute, and it was a third unit of a value already published twice.",
                                                            "properties": {
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "description": "Bytes. The same ceiling as `storage.quota_bytes` on the mailbox object. **Never null**, and not nullable: it is our own figure, read from a NOT NULL column in MySQL, and this endpoint additionally floors it \u2014 a missing quota would publish 0, never null. That is precisely the difference between the two fields in this object, and it is why only `used_bytes` can tell you it does not know: the quota can never be unknown, so a 0 here would mean a real ceiling of zero rather than a figure we failed to read."
                                                                },
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. **null means we could not read the figure, not that the mailbox is empty** \u2014 usage is measured on the mail server and is null whenever the mailbox does not exist there yet. Carries exactly the caveat `storage.used_bytes` on the mailbox object does, and means the same thing."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{account}/retry-provisioning": {
            "post": {
                "operationId": "postEmailAccountsAccountRetryProvisioning",
                "summary": "Retry Provisioning a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the mailbox."
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "description": "The full email address. This *is* the mailbox publicly: there is no separate `username`, because the local part is already in here."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Display name, as it appears to a recipient. null when none was set."
                                                        },
                                                        "domain_id": {
                                                            "type": "string",
                                                            "description": "The domain this mailbox belongs to. Retrieve it with `GET /api/v1/domains/{domain}`."
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mail",
                                                                "smtp",
                                                                "both"
                                                            ],
                                                            "description": "What the mailbox was created as, and what you can filter the list by. Recorded rather than enforced: nothing in the product currently branches on it, so it does not by itself restrict what the mailbox can do."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "suspended",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first: `deleting` outranks everything, then `suspended` (a business decision, whatever the mail server thinks), then what provisioning says. Only an `active` mailbox sends and receives."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "What the mail server has done with this mailbox. Creation is asynchronous, so a mailbox exists here before it exists there.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "The mail server's own lifecycle value, as stored. **Never null**, and not nullable: `email_accounts.provisioning_state` is NOT NULL, defaults to `pending`, and creation writes `pending` explicitly before the row is inserted \u2014 so a mailbox always carries one. It is read from OUR database, not fetched from the mail server, so unlike `storage.used_bytes` it never goes unknown when that host is unreachable; a mail server we cannot reach leaves this value STALE, not absent. Every value the product writes today is in the set above, but rows that predate the column can still hold a spelling that is not \u2014 `provisioned` survives in real data \u2014 so branch on the top-level `state`, which normalises whatever is stored into a set that really is closed."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning failed, in the mail server's words. null unless `state` is `failed`."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "True only while `state` is `failed`, which is the only state `POST /retry-provisioning` accepts."
                                                                }
                                                            }
                                                        },
                                                        "storage": {
                                                            "type": "object",
                                                            "description": "Bytes, both of them. Never a pre-formatted \"3 GB\", which cannot be computed with.",
                                                            "properties": {
                                                                "quota_bytes": {
                                                                    "type": "integer",
                                                                    "description": "Bytes. The ceiling set for this mailbox. **Never null**, and not nullable \u2014 read the contrast with `used_bytes` below, because the two figures in this object have very different reliability. The quota is OUR number, held in MySQL in a NOT NULL column, and a mailbox created without an explicit quota is given one (1 GB), so there is always an answer and it never depends on the mail server being reachable. `used_bytes` is the mail server's number and can be unknown. A null here would mean the mailbox has no ceiling, which is not a state this product can be in."
                                                                },
                                                                "used_bytes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Bytes. **null means we could not read the figure, not that the mailbox is empty** \u2014 usage is measured on the mail server and is null whenever the mailbox does not exist there yet, so there has been nothing to measure. Treat null as \"unknown\" and show it as such: a customer told they have used nothing, when in truth we could not ask, will discover the difference the day they hit the quota. A mailbox that IS provisioned but whose storage has never been synced currently reads 0 rather than null; the column cannot yet express the difference."
                                                                }
                                                            }
                                                        },
                                                        "send_limits": {
                                                            "type": "object",
                                                            "description": "Per-mailbox sending overrides.",
                                                            "properties": {
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per day. **null means no override, not unlimited** \u2014 the organization's plan limit applies instead. A 0 would mean \"may not send\"."
                                                                },
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages per hour. null means no override, exactly as `daily`."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{account}/reset-password": {
            "post": {
                "operationId": "postEmailAccountsAccountResetPassword",
                "summary": "Reset Password a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox_password"
                                                            ]
                                                        },
                                                        "mailbox_id": {
                                                            "type": "string",
                                                            "description": "The mailbox whose password changed. Retrieve it with `GET /api/v1/email-accounts/{email_account}`."
                                                        },
                                                        "password": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "**Returned exactly once, in this response, and never retrievable again.** Store it before you discard the response: we keep it encrypted and no endpoint can read it back, so a lost value can only be replaced by setting another password. Populated by `POST /generate-password`, which generated it. **null from `POST /reset-password`** \u2014 there you supplied the password and already hold it; null there means \"not ours to return\", not \"unknown\"."
                                                        },
                                                        "changed_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When the password moved \u2014 in practice the instant of this request, because both endpoints stamp it as they write and then hand back what they just wrote. **Never null in this response**, and not nullable. The column behind it IS nullable and a mailbox whose password has never been changed holds null there, but the only way to receive this object is to change one, so that null cannot reach you here. The only place the published contract reports this, and only to the caller that just moved it \u2014 the mailbox object carries no credential timestamps, so there is no endpoint that will tell you when some other mailbox's password last changed."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{account}/generate-password": {
            "post": {
                "operationId": "postEmailAccountsAccountGeneratePassword",
                "summary": "Generate Password a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox_password"
                                                            ]
                                                        },
                                                        "mailbox_id": {
                                                            "type": "string",
                                                            "description": "The mailbox whose password changed. Retrieve it with `GET /api/v1/email-accounts/{email_account}`."
                                                        },
                                                        "password": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "**Returned exactly once, in this response, and never retrievable again.** Store it before you discard the response: we keep it encrypted and no endpoint can read it back, so a lost value can only be replaced by setting another password. Populated by `POST /generate-password`, which generated it. **null from `POST /reset-password`** \u2014 there you supplied the password and already hold it; null there means \"not ours to return\", not \"unknown\"."
                                                        },
                                                        "changed_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When the password moved \u2014 in practice the instant of this request, because both endpoints stamp it as they write and then hand back what they just wrote. **Never null in this response**, and not nullable. The column behind it IS nullable and a mailbox whose password has never been changed holds null there, but the only way to receive this object is to change one, so that null cannot reach you here. The only place the published contract reports this, and only to the caller that just moved it \u2014 the mailbox object carries no credential timestamps, so there is no endpoint that will tell you when some other mailbox's password last changed."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{account}/aliases": {
            "get": {
                "operationId": "getEmailAccountsAccountAliases",
                "summary": "Aliases a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "mailbox_alias"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "description": "Unique identifier for the alias."
                                                            },
                                                            "mailbox_id": {
                                                                "type": "string",
                                                                "description": "The mailbox this alias delivers into. Retrieve it with `GET /api/v1/email-accounts/{email_account}`."
                                                            },
                                                            "address": {
                                                                "type": "string",
                                                                "description": "The additional address. An alias **receives only** \u2014 it cannot be used as an SMTP login, and mail sent through it still leaves as the mailbox."
                                                            },
                                                            "state": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "active",
                                                                    "provisioning",
                                                                    "failed",
                                                                    "suspended",
                                                                    "deleting"
                                                                ],
                                                                "description": "The same closed set, and the same ordering, as a mailbox `state`, so one branch in your code handles both. Only an `active` alias routes mail."
                                                            },
                                                            "provisioning": {
                                                                "type": "object",
                                                                "description": "What the mail server has done with this alias. Creation is asynchronous, so an alias exists here before it routes anything there.",
                                                                "properties": {
                                                                    "state": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "pending",
                                                                            "provisioning",
                                                                            "active",
                                                                            "failed",
                                                                            "suspended",
                                                                            "deleting",
                                                                            "deleted"
                                                                        ],
                                                                        "description": "What the mail server has recorded for this alias, as stored. **Never null**, and not nullable: `email_aliases.provisioning_state` is NOT NULL and defaults to `pending`, and an alias is created with `pending` written explicitly. It comes from our database rather than a live call, so an unreachable mail server leaves this STALE rather than unknown \u2014 `provisioning.error` is where a failure gets named, and that one is null when there is genuinely no error. Same set and same meanings as a mailbox's `provisioning.state`."
                                                                    },
                                                                    "error": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Why provisioning failed. null unless `state` is `failed`."
                                                                    },
                                                                    "retryable": {
                                                                        "type": "boolean",
                                                                        "description": "True only while `state` is `failed`, which is the only state `POST /aliases/{alias}/retry-provisioning` accepts."
                                                                    }
                                                                }
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            },
                                                            "updated_at": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postEmailAccountsAccountAliases",
                "summary": "Add an alias",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox_alias"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the alias."
                                                        },
                                                        "mailbox_id": {
                                                            "type": "string",
                                                            "description": "The mailbox this alias delivers into. Retrieve it with `GET /api/v1/email-accounts/{email_account}`."
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "description": "The additional address. An alias **receives only** \u2014 it cannot be used as an SMTP login, and mail sent through it still leaves as the mailbox."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "suspended",
                                                                "deleting"
                                                            ],
                                                            "description": "The same closed set, and the same ordering, as a mailbox `state`, so one branch in your code handles both. Only an `active` alias routes mail."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "What the mail server has done with this alias. Creation is asynchronous, so an alias exists here before it routes anything there.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "What the mail server has recorded for this alias, as stored. **Never null**, and not nullable: `email_aliases.provisioning_state` is NOT NULL and defaults to `pending`, and an alias is created with `pending` written explicitly. It comes from our database rather than a live call, so an unreachable mail server leaves this STALE rather than unknown \u2014 `provisioning.error` is where a failure gets named, and that one is null when there is genuinely no error. Same set and same meanings as a mailbox's `provisioning.state`."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning failed. null unless `state` is `failed`."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "True only while `state` is `failed`, which is the only state `POST /aliases/{alias}/retry-provisioning` accepts."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "An additional address delivering into this mailbox. Aliases cannot be used as SMTP logins; they receive only."
            }
        },
        "/api/v1/email-accounts/{account}/aliases/{alias}": {
            "delete": {
                "operationId": "deleteEmailAccountsAccountAliasesAlias",
                "summary": "Delete a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "alias",
                        "in": "path",
                        "required": true,
                        "description": "The alias identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content; `message` confirms the deletion. An alias that reached the mail server is removed there first and stops routing once that completes, which is asynchronous."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{account}/aliases/{alias}/retry-provisioning": {
            "post": {
                "operationId": "postEmailAccountsAccountAliasesAliasRetryProvisioning",
                "summary": "Retry Provisioning a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "alias",
                        "in": "path",
                        "required": true,
                        "description": "The alias identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox_alias"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the alias."
                                                        },
                                                        "mailbox_id": {
                                                            "type": "string",
                                                            "description": "The mailbox this alias delivers into. Retrieve it with `GET /api/v1/email-accounts/{email_account}`."
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "description": "The additional address. An alias **receives only** \u2014 it cannot be used as an SMTP login, and mail sent through it still leaves as the mailbox."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "provisioning",
                                                                "failed",
                                                                "suspended",
                                                                "deleting"
                                                            ],
                                                            "description": "The same closed set, and the same ordering, as a mailbox `state`, so one branch in your code handles both. Only an `active` alias routes mail."
                                                        },
                                                        "provisioning": {
                                                            "type": "object",
                                                            "description": "What the mail server has done with this alias. Creation is asynchronous, so an alias exists here before it routes anything there.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "provisioning",
                                                                        "active",
                                                                        "failed",
                                                                        "suspended",
                                                                        "deleting",
                                                                        "deleted"
                                                                    ],
                                                                    "description": "What the mail server has recorded for this alias, as stored. **Never null**, and not nullable: `email_aliases.provisioning_state` is NOT NULL and defaults to `pending`, and an alias is created with `pending` written explicitly. It comes from our database rather than a live call, so an unreachable mail server leaves this STALE rather than unknown \u2014 `provisioning.error` is where a failure gets named, and that one is null when there is genuinely no error. Same set and same meanings as a mailbox's `provisioning.state`."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why provisioning failed. null unless `state` is `failed`."
                                                                },
                                                                "retryable": {
                                                                    "type": "boolean",
                                                                    "description": "True only while `state` is `failed`, which is the only state `POST /aliases/{alias}/retry-provisioning` accepts."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{account}/forwarding-rules": {
            "get": {
                "operationId": "getEmailAccountsAccountForwardingRules",
                "summary": "Forwarding Rules a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "mailbox_forwarding_rule"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "description": "Unique identifier for the rule."
                                                            },
                                                            "mailbox_id": {
                                                                "type": "string",
                                                                "description": "The mailbox this rule applies to. Retrieve it with `GET /api/v1/email-accounts/{email_account}`."
                                                            },
                                                            "forward_to": {
                                                                "type": "string",
                                                                "description": "The address mail is forwarded to."
                                                            },
                                                            "condition": {
                                                                "type": "object",
                                                                "description": "When the rule applies. The two halves travel together because they are meaningless apart.",
                                                                "properties": {
                                                                    "type": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "all",
                                                                            "from",
                                                                            "subject",
                                                                            "has_attachment"
                                                                        ],
                                                                        "description": "`all` forwards everything; `from` and `subject` match `value`; `has_attachment` needs no value."
                                                                    },
                                                                    "value": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The address or subject fragment matched on. **null when `type` is `all` or `has_attachment`**, where there is nothing to match against \u2014 not an unknown value."
                                                                    }
                                                                }
                                                            },
                                                            "keep_copy": {
                                                                "type": "boolean",
                                                                "description": "Whether the original is also left in the mailbox. False forwards and removes."
                                                            },
                                                            "active": {
                                                                "type": "boolean",
                                                                "description": "Whether the rule is switched on. A plain flag rather than a `state`, because a forwarding rule has no mail-server lifecycle to disagree with it \u2014 nothing carries the rule to the mail server, so `true` means the rule is stored and enabled here, which is not the same statement as \"mail is being forwarded\"."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            },
                                                            "updated_at": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postEmailAccountsAccountForwardingRules",
                "summary": "Forwarding Rules a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox_forwarding_rule"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the rule."
                                                        },
                                                        "mailbox_id": {
                                                            "type": "string",
                                                            "description": "The mailbox this rule applies to. Retrieve it with `GET /api/v1/email-accounts/{email_account}`."
                                                        },
                                                        "forward_to": {
                                                            "type": "string",
                                                            "description": "The address mail is forwarded to."
                                                        },
                                                        "condition": {
                                                            "type": "object",
                                                            "description": "When the rule applies. The two halves travel together because they are meaningless apart.",
                                                            "properties": {
                                                                "type": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "all",
                                                                        "from",
                                                                        "subject",
                                                                        "has_attachment"
                                                                    ],
                                                                    "description": "`all` forwards everything; `from` and `subject` match `value`; `has_attachment` needs no value."
                                                                },
                                                                "value": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The address or subject fragment matched on. **null when `type` is `all` or `has_attachment`**, where there is nothing to match against \u2014 not an unknown value."
                                                                }
                                                            }
                                                        },
                                                        "keep_copy": {
                                                            "type": "boolean",
                                                            "description": "Whether the original is also left in the mailbox. False forwards and removes."
                                                        },
                                                        "active": {
                                                            "type": "boolean",
                                                            "description": "Whether the rule is switched on. A plain flag rather than a `state`, because a forwarding rule has no mail-server lifecycle to disagree with it \u2014 nothing carries the rule to the mail server, so `true` means the rule is stored and enabled here, which is not the same statement as \"mail is being forwarded\"."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-accounts/{account}/forwarding-rules/{rule}": {
            "put": {
                "operationId": "putEmailAccountsAccountForwardingRulesRule",
                "summary": "Update a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "rule",
                        "in": "path",
                        "required": true,
                        "description": "The rule identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "mailbox_forwarding_rule"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the rule."
                                                        },
                                                        "mailbox_id": {
                                                            "type": "string",
                                                            "description": "The mailbox this rule applies to. Retrieve it with `GET /api/v1/email-accounts/{email_account}`."
                                                        },
                                                        "forward_to": {
                                                            "type": "string",
                                                            "description": "The address mail is forwarded to."
                                                        },
                                                        "condition": {
                                                            "type": "object",
                                                            "description": "When the rule applies. The two halves travel together because they are meaningless apart.",
                                                            "properties": {
                                                                "type": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "all",
                                                                        "from",
                                                                        "subject",
                                                                        "has_attachment"
                                                                    ],
                                                                    "description": "`all` forwards everything; `from` and `subject` match `value`; `has_attachment` needs no value."
                                                                },
                                                                "value": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The address or subject fragment matched on. **null when `type` is `all` or `has_attachment`**, where there is nothing to match against \u2014 not an unknown value."
                                                                }
                                                            }
                                                        },
                                                        "keep_copy": {
                                                            "type": "boolean",
                                                            "description": "Whether the original is also left in the mailbox. False forwards and removes."
                                                        },
                                                        "active": {
                                                            "type": "boolean",
                                                            "description": "Whether the rule is switched on. A plain flag rather than a `state`, because a forwarding rule has no mail-server lifecycle to disagree with it \u2014 nothing carries the rule to the mail server, so `true` means the rule is stored and enabled here, which is not the same statement as \"mail is being forwarded\"."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteEmailAccountsAccountForwardingRulesRule",
                "summary": "Delete a email account",
                "tags": [
                    "Mailboxes"
                ],
                "x-required-scope": "mailboxes:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "account",
                        "in": "path",
                        "required": true,
                        "description": "The account identifier.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "rule",
                        "in": "path",
                        "required": true,
                        "description": "The rule identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content; `message` confirms the deletion. The rule is removed immediately and completely."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/senders": {
            "get": {
                "operationId": "getSenders",
                "summary": "List senders",
                "tags": [
                    "Senders"
                ],
                "x-required-scope": "senders:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "sender"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Unique identifier for the sender."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "description": "The display name recipients see, e.g. `Acme Support` in `Acme Support <hello@acme.com>`."
                                                                    },
                                                                    "email": {
                                                                        "type": "string",
                                                                        "format": "email",
                                                                        "description": "The address this identity sends as. `POST /messages` refuses a `from` that is not a verified sender."
                                                                    },
                                                                    "domain": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The domain NAME this address sends from, e.g. `acme.com` \u2014 not an id. A sender owns no DNS state of its own; it reads its domain's, so the full DNS picture is at `GET /domains/{domain}` and is deliberately not duplicated here. **null means UNKNOWN \u2014 the domain relation was not loaded on this path, so we did not read the name.** It NEVER means the sender has no domain: `senders.domain_id` is NOT NULL, so every sender has exactly one. Every published path loads the relation, so a null here is our omission rather than a fact about the sender."
                                                                    },
                                                                    "verification": {
                                                                        "type": "object",
                                                                        "description": "Whether this identity may be sent from. **No verification token appears here or anywhere else in the API** \u2014 verification reads the domain's public DNS, so there is nothing to prove ownership with. If a token-based flow is ever added, its token belongs in the response to the request that mints it and nowhere else: a token that claims an address is a credential, and one returned on a GET is readable by anyone who can replay the request.",
                                                                        "properties": {
                                                                            "state": {
                                                                                "type": "string",
                                                                                "enum": [
                                                                                    "pending",
                                                                                    "verified",
                                                                                    "failed"
                                                                                ],
                                                                                "description": "The one verification answer. Only `verified` permits sending; `pending` and `failed` both do not, and differ in whether a check has run."
                                                                            },
                                                                            "verified_at": {
                                                                                "type": "string",
                                                                                "format": "date-time",
                                                                                "nullable": true,
                                                                                "description": "When the last SUCCESSFUL check ran. **null means NOT INCLUDED \u2014 it is withheld whenever `state` is not `verified`**, and that is the one place in this section where a null is a deliberate withholding rather than an absence. The stored column is NOT cleared when a later check fails, so a sender that verified in March and broke its SPF in April still carries the March date; publishing it beside `state: \"failed\"` would be two fields giving two answers. So null here does not mean this sender never verified \u2014 it means it is not verified NOW, and any earlier success is deliberately not published. Read `state` for whether this sender works, never this field."
                                                                            },
                                                                            "error": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "Why the last check failed, in words a customer can act on (typically the DNS records still missing). **null means NONE \u2014 there is no current failure to report**, which is the case whenever `state` is not `failed`. Unlike `verified_at` above, nothing is being withheld here: a successful check clears the stored error, so there is no stale string to hide."
                                                                            }
                                                                        }
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When this sender was created. Written on insert, so it should always be present. **null means UNKNOWN \u2014 the stored timestamp was absent**, and we will not invent a date to fill the gap."
                                                                    },
                                                                    "updated_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When this sender was last changed. **null means UNKNOWN \u2014 the stored timestamp was absent.** It never means \"never changed\": a sender that has not been touched since creation carries its creation time here."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postSenders",
                "summary": "Add a sending identity",
                "tags": [
                    "Senders"
                ],
                "x-required-scope": "senders:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "sender"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the sender."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The display name recipients see, e.g. `Acme Support` in `Acme Support <hello@acme.com>`."
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "The address this identity sends as. `POST /messages` refuses a `from` that is not a verified sender."
                                                        },
                                                        "domain": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The domain NAME this address sends from, e.g. `acme.com` \u2014 not an id. A sender owns no DNS state of its own; it reads its domain's, so the full DNS picture is at `GET /domains/{domain}` and is deliberately not duplicated here. **null means UNKNOWN \u2014 the domain relation was not loaded on this path, so we did not read the name.** It NEVER means the sender has no domain: `senders.domain_id` is NOT NULL, so every sender has exactly one. Every published path loads the relation, so a null here is our omission rather than a fact about the sender."
                                                        },
                                                        "verification": {
                                                            "type": "object",
                                                            "description": "Whether this identity may be sent from. **No verification token appears here or anywhere else in the API** \u2014 verification reads the domain's public DNS, so there is nothing to prove ownership with. If a token-based flow is ever added, its token belongs in the response to the request that mints it and nowhere else: a token that claims an address is a credential, and one returned on a GET is readable by anyone who can replay the request.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "verified",
                                                                        "failed"
                                                                    ],
                                                                    "description": "The one verification answer. Only `verified` permits sending; `pending` and `failed` both do not, and differ in whether a check has run."
                                                                },
                                                                "verified_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the last SUCCESSFUL check ran. **null means NOT INCLUDED \u2014 it is withheld whenever `state` is not `verified`**, and that is the one place in this section where a null is a deliberate withholding rather than an absence. The stored column is NOT cleared when a later check fails, so a sender that verified in March and broke its SPF in April still carries the March date; publishing it beside `state: \"failed\"` would be two fields giving two answers. So null here does not mean this sender never verified \u2014 it means it is not verified NOW, and any earlier success is deliberately not published. Read `state` for whether this sender works, never this field."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why the last check failed, in words a customer can act on (typically the DNS records still missing). **null means NONE \u2014 there is no current failure to report**, which is the case whenever `state` is not `failed`. Unlike `verified_at` above, nothing is being withheld here: a successful check clears the stored error, so there is no stale string to hide."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When this sender was created. Written on insert, so it should always be present. **null means UNKNOWN \u2014 the stored timestamp was absent**, and we will not invent a date to fill the gap."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When this sender was last changed. **null means UNKNOWN \u2014 the stored timestamp was absent.** It never means \"never changed\": a sender that has not been touched since creation carries its creation time here."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "A sender is an identity you are allowed to send *as* \u2014 a name and address, like\n`Ada from Acme <ada@acme.com>`.\n\nThis is not the same as a mailbox, and not the same as an SMTP credential. A mailbox\nreceives; a credential authenticates; a sender is what appears in the `From:` header.\n`POST /messages` refuses a `from` address that is not a verified sender here."
            }
        },
        "/api/v1/senders/{sender}": {
            "get": {
                "operationId": "getSendersSender",
                "summary": "Retrieve a sender",
                "tags": [
                    "Senders"
                ],
                "x-required-scope": "senders:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "sender",
                        "in": "path",
                        "required": true,
                        "description": "The sender identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "sender"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the sender."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The display name recipients see, e.g. `Acme Support` in `Acme Support <hello@acme.com>`."
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "The address this identity sends as. `POST /messages` refuses a `from` that is not a verified sender."
                                                        },
                                                        "domain": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The domain NAME this address sends from, e.g. `acme.com` \u2014 not an id. A sender owns no DNS state of its own; it reads its domain's, so the full DNS picture is at `GET /domains/{domain}` and is deliberately not duplicated here. **null means UNKNOWN \u2014 the domain relation was not loaded on this path, so we did not read the name.** It NEVER means the sender has no domain: `senders.domain_id` is NOT NULL, so every sender has exactly one. Every published path loads the relation, so a null here is our omission rather than a fact about the sender."
                                                        },
                                                        "verification": {
                                                            "type": "object",
                                                            "description": "Whether this identity may be sent from. **No verification token appears here or anywhere else in the API** \u2014 verification reads the domain's public DNS, so there is nothing to prove ownership with. If a token-based flow is ever added, its token belongs in the response to the request that mints it and nowhere else: a token that claims an address is a credential, and one returned on a GET is readable by anyone who can replay the request.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "verified",
                                                                        "failed"
                                                                    ],
                                                                    "description": "The one verification answer. Only `verified` permits sending; `pending` and `failed` both do not, and differ in whether a check has run."
                                                                },
                                                                "verified_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the last SUCCESSFUL check ran. **null means NOT INCLUDED \u2014 it is withheld whenever `state` is not `verified`**, and that is the one place in this section where a null is a deliberate withholding rather than an absence. The stored column is NOT cleared when a later check fails, so a sender that verified in March and broke its SPF in April still carries the March date; publishing it beside `state: \"failed\"` would be two fields giving two answers. So null here does not mean this sender never verified \u2014 it means it is not verified NOW, and any earlier success is deliberately not published. Read `state` for whether this sender works, never this field."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why the last check failed, in words a customer can act on (typically the DNS records still missing). **null means NONE \u2014 there is no current failure to report**, which is the case whenever `state` is not `failed`. Unlike `verified_at` above, nothing is being withheld here: a successful check clears the stored error, so there is no stale string to hide."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When this sender was created. Written on insert, so it should always be present. **null means UNKNOWN \u2014 the stored timestamp was absent**, and we will not invent a date to fill the gap."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When this sender was last changed. **null means UNKNOWN \u2014 the stored timestamp was absent.** It never means \"never changed\": a sender that has not been touched since creation carries its creation time here."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "operationId": "putSendersSender",
                "summary": "Update a sender",
                "tags": [
                    "Senders"
                ],
                "x-required-scope": "senders:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "sender",
                        "in": "path",
                        "required": true,
                        "description": "The sender identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "sender"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the sender."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The display name recipients see, e.g. `Acme Support` in `Acme Support <hello@acme.com>`."
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "The address this identity sends as. `POST /messages` refuses a `from` that is not a verified sender."
                                                        },
                                                        "domain": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The domain NAME this address sends from, e.g. `acme.com` \u2014 not an id. A sender owns no DNS state of its own; it reads its domain's, so the full DNS picture is at `GET /domains/{domain}` and is deliberately not duplicated here. **null means UNKNOWN \u2014 the domain relation was not loaded on this path, so we did not read the name.** It NEVER means the sender has no domain: `senders.domain_id` is NOT NULL, so every sender has exactly one. Every published path loads the relation, so a null here is our omission rather than a fact about the sender."
                                                        },
                                                        "verification": {
                                                            "type": "object",
                                                            "description": "Whether this identity may be sent from. **No verification token appears here or anywhere else in the API** \u2014 verification reads the domain's public DNS, so there is nothing to prove ownership with. If a token-based flow is ever added, its token belongs in the response to the request that mints it and nowhere else: a token that claims an address is a credential, and one returned on a GET is readable by anyone who can replay the request.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "verified",
                                                                        "failed"
                                                                    ],
                                                                    "description": "The one verification answer. Only `verified` permits sending; `pending` and `failed` both do not, and differ in whether a check has run."
                                                                },
                                                                "verified_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the last SUCCESSFUL check ran. **null means NOT INCLUDED \u2014 it is withheld whenever `state` is not `verified`**, and that is the one place in this section where a null is a deliberate withholding rather than an absence. The stored column is NOT cleared when a later check fails, so a sender that verified in March and broke its SPF in April still carries the March date; publishing it beside `state: \"failed\"` would be two fields giving two answers. So null here does not mean this sender never verified \u2014 it means it is not verified NOW, and any earlier success is deliberately not published. Read `state` for whether this sender works, never this field."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why the last check failed, in words a customer can act on (typically the DNS records still missing). **null means NONE \u2014 there is no current failure to report**, which is the case whenever `state` is not `failed`. Unlike `verified_at` above, nothing is being withheld here: a successful check clears the stored error, so there is no stale string to hide."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When this sender was created. Written on insert, so it should always be present. **null means UNKNOWN \u2014 the stored timestamp was absent**, and we will not invent a date to fill the gap."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When this sender was last changed. **null means UNKNOWN \u2014 the stored timestamp was absent.** It never means \"never changed\": a sender that has not been touched since creation carries its creation time here."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "operationId": "patchSendersSender",
                "summary": "Update a sender",
                "tags": [
                    "Senders"
                ],
                "x-required-scope": "senders:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "sender",
                        "in": "path",
                        "required": true,
                        "description": "The sender identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "sender"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the sender."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The display name recipients see, e.g. `Acme Support` in `Acme Support <hello@acme.com>`."
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "The address this identity sends as. `POST /messages` refuses a `from` that is not a verified sender."
                                                        },
                                                        "domain": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The domain NAME this address sends from, e.g. `acme.com` \u2014 not an id. A sender owns no DNS state of its own; it reads its domain's, so the full DNS picture is at `GET /domains/{domain}` and is deliberately not duplicated here. **null means UNKNOWN \u2014 the domain relation was not loaded on this path, so we did not read the name.** It NEVER means the sender has no domain: `senders.domain_id` is NOT NULL, so every sender has exactly one. Every published path loads the relation, so a null here is our omission rather than a fact about the sender."
                                                        },
                                                        "verification": {
                                                            "type": "object",
                                                            "description": "Whether this identity may be sent from. **No verification token appears here or anywhere else in the API** \u2014 verification reads the domain's public DNS, so there is nothing to prove ownership with. If a token-based flow is ever added, its token belongs in the response to the request that mints it and nowhere else: a token that claims an address is a credential, and one returned on a GET is readable by anyone who can replay the request.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "verified",
                                                                        "failed"
                                                                    ],
                                                                    "description": "The one verification answer. Only `verified` permits sending; `pending` and `failed` both do not, and differ in whether a check has run."
                                                                },
                                                                "verified_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the last SUCCESSFUL check ran. **null means NOT INCLUDED \u2014 it is withheld whenever `state` is not `verified`**, and that is the one place in this section where a null is a deliberate withholding rather than an absence. The stored column is NOT cleared when a later check fails, so a sender that verified in March and broke its SPF in April still carries the March date; publishing it beside `state: \"failed\"` would be two fields giving two answers. So null here does not mean this sender never verified \u2014 it means it is not verified NOW, and any earlier success is deliberately not published. Read `state` for whether this sender works, never this field."
                                                                },
                                                                "error": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why the last check failed, in words a customer can act on (typically the DNS records still missing). **null means NONE \u2014 there is no current failure to report**, which is the case whenever `state` is not `failed`. Unlike `verified_at` above, nothing is being withheld here: a successful check clears the stored error, so there is no stale string to hide."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When this sender was created. Written on insert, so it should always be present. **null means UNKNOWN \u2014 the stored timestamp was absent**, and we will not invent a date to fill the gap."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When this sender was last changed. **null means UNKNOWN \u2014 the stored timestamp was absent.** It never means \"never changed\": a sender that has not been touched since creation carries its creation time here."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteSendersSender",
                "summary": "Delete a sender",
                "tags": [
                    "Senders"
                ],
                "x-required-scope": "senders:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "sender",
                        "in": "path",
                        "required": true,
                        "description": "The sender identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "The sender was deleted. No object is returned: `data` is null. The sender stops appearing in `GET /senders` and reads of it return 404."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/senders/{sender}/verification": {
            "get": {
                "operationId": "getSendersSenderVerification",
                "summary": "Verification a sender",
                "tags": [
                    "Senders"
                ],
                "x-required-scope": "senders:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "sender",
                        "in": "path",
                        "required": true,
                        "description": "The sender identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The live verification picture for one sender: what DNS looks like right now and what is missing. **No verification token is published** \u2014 verification reads the domain's public DNS and there is no secret in this flow. A token that proves ownership of an address is a credential; if one is ever introduced it must not appear on a read endpoint.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "sender_verification"
                                                            ]
                                                        },
                                                        "sender_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The sender this picture describes. **null means UNKNOWN \u2014 the id was missing from the payload.** It never means the picture belongs to no sender: both endpoints build it from the sender they have just read, whose id is a NOT NULL primary key, so a null here would be our fault rather than a state a sender can be in."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "pending",
                                                                "verified",
                                                                "failed"
                                                            ],
                                                            "description": "The same closed set, from the same function, that `GET /senders/{sender}` publishes under `verification.state`, so one sender cannot read `failed` on one endpoint and something else on the other. Note there is deliberately NO timestamp here: when a sender last verified is durable state and is published once, on the sender itself."
                                                        },
                                                        "error": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Why the last check failed. **null means NONE \u2014 there is no current failure**, which is the case whenever `state` is not `failed`. A stale error beside a `verified` state is the same contradiction as a stale timestamp beside a failure, and a successful check clears the stored string, so there is nothing withheld here."
                                                        },
                                                        "checks": {
                                                            "type": "object",
                                                            "description": "The live DNS lookups, each genuinely true or false. There is no third \"unknown\" state to represent: these resolve the domain's published records, and a record that will not resolve has not been published. This is one of the few places in the API where `false` really does mean false rather than \"not measured\".",
                                                            "properties": {
                                                                "spf": {
                                                                    "type": "boolean"
                                                                },
                                                                "dkim": {
                                                                    "type": "boolean"
                                                                },
                                                                "dmarc": {
                                                                    "type": "boolean",
                                                                    "description": "Reported, but never required \u2014 see `requires`."
                                                                }
                                                            }
                                                        },
                                                        "requires": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "spf",
                                                                    "dkim"
                                                                ]
                                                            },
                                                            "description": "Which of `checks` must pass for this sender to verify. NARROWER than `checks`: DMARC is checked and reported but is advisory, not a delivery gate. Published because a caller looking at three booleans would otherwise reasonably conclude all three must be true."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/senders/{sender}/verify": {
            "post": {
                "operationId": "postSendersSenderVerify",
                "summary": "Verify a sender",
                "tags": [
                    "Senders"
                ],
                "x-required-scope": "senders:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "sender",
                        "in": "path",
                        "required": true,
                        "description": "The sender identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The live verification picture for one sender: what DNS looks like right now and what is missing. **No verification token is published** \u2014 verification reads the domain's public DNS and there is no secret in this flow. A token that proves ownership of an address is a credential; if one is ever introduced it must not appear on a read endpoint.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "sender_verification"
                                                            ]
                                                        },
                                                        "sender_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The sender this picture describes. **null means UNKNOWN \u2014 the id was missing from the payload.** It never means the picture belongs to no sender: both endpoints build it from the sender they have just read, whose id is a NOT NULL primary key, so a null here would be our fault rather than a state a sender can be in."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "pending",
                                                                "verified",
                                                                "failed"
                                                            ],
                                                            "description": "The same closed set, from the same function, that `GET /senders/{sender}` publishes under `verification.state`, so one sender cannot read `failed` on one endpoint and something else on the other. Note there is deliberately NO timestamp here: when a sender last verified is durable state and is published once, on the sender itself."
                                                        },
                                                        "error": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Why the last check failed. **null means NONE \u2014 there is no current failure**, which is the case whenever `state` is not `failed`. A stale error beside a `verified` state is the same contradiction as a stale timestamp beside a failure, and a successful check clears the stored string, so there is nothing withheld here."
                                                        },
                                                        "checks": {
                                                            "type": "object",
                                                            "description": "The live DNS lookups, each genuinely true or false. There is no third \"unknown\" state to represent: these resolve the domain's published records, and a record that will not resolve has not been published. This is one of the few places in the API where `false` really does mean false rather than \"not measured\".",
                                                            "properties": {
                                                                "spf": {
                                                                    "type": "boolean"
                                                                },
                                                                "dkim": {
                                                                    "type": "boolean"
                                                                },
                                                                "dmarc": {
                                                                    "type": "boolean",
                                                                    "description": "Reported, but never required \u2014 see `requires`."
                                                                }
                                                            }
                                                        },
                                                        "requires": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "spf",
                                                                    "dkim"
                                                                ]
                                                            },
                                                            "description": "Which of `checks` must pass for this sender to verify. NARROWER than `checks`: DMARC is checked and reported but is advisory, not a delivery gate. Published because a caller looking at three booleans would otherwise reasonably conclude all three must be true."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/smtp-credentials": {
            "get": {
                "operationId": "getSmtpCredentials",
                "summary": "List smtp credentials",
                "tags": [
                    "SMTP credentials"
                ],
                "x-required-scope": "smtp:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "smtp_credential"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "description": "Unique identifier for the credential."
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "description": "Your label for it. Not used in authentication. Never null: `smtp_credentials.name` is NOT NULL and creation requires it."
                                                            },
                                                            "username": {
                                                                "type": "string",
                                                                "description": "The SMTP AUTH username, and the credential's public identity: it is what you configure in your mail library and what delivery events are attributed to. Safe to log. Never null: the column is NOT NULL and unique, and the mail server assigns it at creation -- a credential cannot exist without one."
                                                            },
                                                            "state": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "active",
                                                                    "revoked",
                                                                    "pending_review",
                                                                    "provisioning",
                                                                    "failed",
                                                                    "deleting"
                                                                ],
                                                                "description": "The one lifecycle answer, ordered by what stops you first. `deleting` and `failed` beat everything: a credential being torn down cannot authenticate however active it looks. `pending_review` is a marketing-stream credential awaiting approval -- provisioned, but refused at AUTH time until it is reviewed. Only `active` can send."
                                                            },
                                                            "stream": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "transactional",
                                                                    "marketing"
                                                                ],
                                                                "description": "Which lane mail sent with this credential is treated as. The stream decides reputation handling and marketing gating; it is not a label."
                                                            },
                                                            "domain": {
                                                                "type": "object",
                                                                "description": "The one domain this credential may send as. Always present, and `id` is always populated -- it is only `name` that some responses cannot fill.",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "**Never null.** A credential cannot exist without a domain: `smtp_credentials.domain_id` is a NOT NULL foreign key, creation requires a `domain_id` that exists, and deleting the domain deletes the credential with it. So this is the field to key off when `name` is null -- fetch `GET /domains/{domain}` with it."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "**null means the domain relation was NOT LOADED for this response, so its name is unknown to us here** -- it does NOT mean the credential has no domain, which is impossible, and it is not an empty name. Only `GET /smtp-credentials` eager-loads the relation; create, update, rotate, revoke, enable and the allowlist update all build their response from the credential row alone and report null. That asymmetry is a bug on our side, recorded in the report and not yet fixed -- null is the honest reading of it rather than a cover for it. `domain.id` is correct in every response, so resolve the name from that, or re-read the credential from the list endpoint."
                                                                    }
                                                                }
                                                            },
                                                            "ip_allowlist": {
                                                                "type": "object",
                                                                "description": "Enforced by the mail server at AUTH time, not by this API. `enabled: false` with a populated list is a configured allowlist that is currently off, not a contradiction.",
                                                                "properties": {
                                                                    "enabled": {
                                                                        "type": "boolean"
                                                                    },
                                                                    "addresses": {
                                                                        "type": "array",
                                                                        "items": {
                                                                            "type": "string"
                                                                        },
                                                                        "description": "IPv4/IPv6 addresses or CIDR ranges."
                                                                    }
                                                                }
                                                            },
                                                            "limits": {
                                                                "type": "object",
                                                                "description": "Per-credential OVERRIDES of your organization's sending tier. These mirror the cap the mail server holds for this credential and are written when it is created or updated through this API; enforcement reads the mail server's own columns, never these.",
                                                                "properties": {
                                                                    "hourly": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Recipients per hour. **null means NONE -- no per-credential override is set. It does not mean unlimited**, and it does not mean the credential may send nothing: your organization's tier still applies underneath, and it is the thing actually enforced. A client that reads null as \"no cap\" and removes its own throttle is the misreading this wording exists to prevent."
                                                                    },
                                                                    "daily": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Recipients per day. null means NONE -- no per-credential override, exactly as for `hourly`, and not unlimited."
                                                                    }
                                                                }
                                                            },
                                                            "tracking_enabled": {
                                                                "type": "boolean",
                                                                "description": "Whether open and click tracking is injected into HTML sent with this credential."
                                                            },
                                                            "last_used_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true,
                                                                "description": "ISO 8601 UTC, and **this field is a MIRROR, not a meter** -- read the null accordingly. Nothing in this API writes it: SMTP AUTH happens on the mail server, and an hourly reconcile copies the timestamp across. So null has two readings and you cannot tell them apart from here. Usually it is NONE -- the mail server has never seen this credential authenticate. But it is UNKNOWN whenever the mirror has not caught up: a credential that has not finished provisioning is never asked about at all, and a credential the mail server was unreachable for is skipped until the next hourly run. **A populated value can be up to an hour behind**, and the sync only ever copies a non-null timestamp across, so it never reverts to null once set. Treat null as \"no evidence of use yet\" rather than as proof a credential is idle, and do not revoke on it alone. For a figure read from the mail server at request time, call `GET /smtp-credentials/{credential}/usage`."
                                                            },
                                                            "expires_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true,
                                                                "description": "ISO 8601 UTC. **null means the credential does not expire** -- NONE, no expiry is set, which is the default. **Do not read null as \"expired\"** and do not read it as unknown: a client that treats a null date as a past one will stop sending with a credential that works. Expiry is enforced by the mail server at AUTH time, and `state` already reflects what our mirror knows about it."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "description": "ISO 8601 UTC."
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postSmtpCredentials",
                "summary": "Create an SMTP credential",
                "tags": [
                    "SMTP credentials"
                ],
                "x-required-scope": "smtp:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "smtp_credential"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the credential."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Your label for it. Not used in authentication. Never null: `smtp_credentials.name` is NOT NULL and creation requires it."
                                                        },
                                                        "username": {
                                                            "type": "string",
                                                            "description": "The SMTP AUTH username, and the credential's public identity: it is what you configure in your mail library and what delivery events are attributed to. Safe to log. Never null: the column is NOT NULL and unique, and the mail server assigns it at creation -- a credential cannot exist without one."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "revoked",
                                                                "pending_review",
                                                                "provisioning",
                                                                "failed",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first. `deleting` and `failed` beat everything: a credential being torn down cannot authenticate however active it looks. `pending_review` is a marketing-stream credential awaiting approval -- provisioned, but refused at AUTH time until it is reviewed. Only `active` can send."
                                                        },
                                                        "stream": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transactional",
                                                                "marketing"
                                                            ],
                                                            "description": "Which lane mail sent with this credential is treated as. The stream decides reputation handling and marketing gating; it is not a label."
                                                        },
                                                        "domain": {
                                                            "type": "object",
                                                            "description": "The one domain this credential may send as. Always present, and `id` is always populated -- it is only `name` that some responses cannot fill.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string",
                                                                    "description": "**Never null.** A credential cannot exist without a domain: `smtp_credentials.domain_id` is a NOT NULL foreign key, creation requires a `domain_id` that exists, and deleting the domain deletes the credential with it. So this is the field to key off when `name` is null -- fetch `GET /domains/{domain}` with it."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "**null means the domain relation was NOT LOADED for this response, so its name is unknown to us here** -- it does NOT mean the credential has no domain, which is impossible, and it is not an empty name. Only `GET /smtp-credentials` eager-loads the relation; create, update, rotate, revoke, enable and the allowlist update all build their response from the credential row alone and report null. That asymmetry is a bug on our side, recorded in the report and not yet fixed -- null is the honest reading of it rather than a cover for it. `domain.id` is correct in every response, so resolve the name from that, or re-read the credential from the list endpoint."
                                                                }
                                                            }
                                                        },
                                                        "ip_allowlist": {
                                                            "type": "object",
                                                            "description": "Enforced by the mail server at AUTH time, not by this API. `enabled: false` with a populated list is a configured allowlist that is currently off, not a contradiction.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "addresses": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "IPv4/IPv6 addresses or CIDR ranges."
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "Per-credential OVERRIDES of your organization's sending tier. These mirror the cap the mail server holds for this credential and are written when it is created or updated through this API; enforcement reads the mail server's own columns, never these.",
                                                            "properties": {
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per hour. **null means NONE -- no per-credential override is set. It does not mean unlimited**, and it does not mean the credential may send nothing: your organization's tier still applies underneath, and it is the thing actually enforced. A client that reads null as \"no cap\" and removes its own throttle is the misreading this wording exists to prevent."
                                                                },
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per day. null means NONE -- no per-credential override, exactly as for `hourly`, and not unlimited."
                                                                }
                                                            }
                                                        },
                                                        "tracking_enabled": {
                                                            "type": "boolean",
                                                            "description": "Whether open and click tracking is injected into HTML sent with this credential."
                                                        },
                                                        "last_used_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC, and **this field is a MIRROR, not a meter** -- read the null accordingly. Nothing in this API writes it: SMTP AUTH happens on the mail server, and an hourly reconcile copies the timestamp across. So null has two readings and you cannot tell them apart from here. Usually it is NONE -- the mail server has never seen this credential authenticate. But it is UNKNOWN whenever the mirror has not caught up: a credential that has not finished provisioning is never asked about at all, and a credential the mail server was unreachable for is skipped until the next hourly run. **A populated value can be up to an hour behind**, and the sync only ever copies a non-null timestamp across, so it never reverts to null once set. Treat null as \"no evidence of use yet\" rather than as proof a credential is idle, and do not revoke on it alone. For a figure read from the mail server at request time, call `GET /smtp-credentials/{credential}/usage`."
                                                        },
                                                        "expires_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means the credential does not expire** -- NONE, no expiry is set, which is the default. **Do not read null as \"expired\"** and do not read it as unknown: a client that treats a null date as a past one will stop sending with a credential that works. Expiry is enforced by the mail server at AUTH time, and `state` already reflects what our mirror knows about it."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "ISO 8601 UTC."
                                                        },
                                                        "password": {
                                                            "type": "string",
                                                            "description": "**Returned once, when the credential is created, and once more each time it is rotated. Never on a read, and it cannot be retrieved again.** It exists only in the mail server's create and rotate responses and is stored nowhere in this API, so nobody -- including Mailyte -- can read it back. Store it when you receive it; if you lose it, rotate rather than recreate. The key is ABSENT rather than null on every other response: `null` would say this credential has no password, which is never true."
                                                        },
                                                        "smtp": {
                                                            "type": "object",
                                                            "description": "Where to send with it, returned **on create only** so a client can be configured from a single response. **The whole object is ABSENT, not null, on every other operation** -- including rotate, which mints a new password but does not repeat the host and port. Do not infer it from the presence of `password`. When it is present both members are always populated, so neither is nullable; the submission endpoint is the same for every credential and does not vary by organization, so it is safe to read once and keep.",
                                                            "properties": {
                                                                "host": {
                                                                    "type": "string",
                                                                    "description": "SMTP submission host."
                                                                },
                                                                "port": {
                                                                    "type": "integer",
                                                                    "description": "SMTP submission port."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "A username and password for relaying mail over SMTP, scoped to one domain.\n\n**The password is shown once.** It is stored only as a hash, so nobody \u2014 including\nMailyte \u2014 can read it back. If it is lost, rotate rather than recreate.\n\nUse SMTP when you have an existing application or library that speaks it. Use\n[`POST /messages`](/developer/api/sending/post-messages) when you are writing the\nintegration yourself: it gives you message ids, tags and per-message delivery events\nthat SMTP submission cannot."
            }
        },
        "/api/v1/smtp-credentials/{credential}": {
            "patch": {
                "operationId": "patchSmtpCredentialsCredential",
                "summary": "Update a smtp credential",
                "tags": [
                    "SMTP credentials"
                ],
                "x-required-scope": "smtp:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "credential",
                        "in": "path",
                        "required": true,
                        "description": "The credential identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "smtp_credential"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the credential."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Your label for it. Not used in authentication. Never null: `smtp_credentials.name` is NOT NULL and creation requires it."
                                                        },
                                                        "username": {
                                                            "type": "string",
                                                            "description": "The SMTP AUTH username, and the credential's public identity: it is what you configure in your mail library and what delivery events are attributed to. Safe to log. Never null: the column is NOT NULL and unique, and the mail server assigns it at creation -- a credential cannot exist without one."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "revoked",
                                                                "pending_review",
                                                                "provisioning",
                                                                "failed",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first. `deleting` and `failed` beat everything: a credential being torn down cannot authenticate however active it looks. `pending_review` is a marketing-stream credential awaiting approval -- provisioned, but refused at AUTH time until it is reviewed. Only `active` can send."
                                                        },
                                                        "stream": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transactional",
                                                                "marketing"
                                                            ],
                                                            "description": "Which lane mail sent with this credential is treated as. The stream decides reputation handling and marketing gating; it is not a label."
                                                        },
                                                        "domain": {
                                                            "type": "object",
                                                            "description": "The one domain this credential may send as. Always present, and `id` is always populated -- it is only `name` that some responses cannot fill.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string",
                                                                    "description": "**Never null.** A credential cannot exist without a domain: `smtp_credentials.domain_id` is a NOT NULL foreign key, creation requires a `domain_id` that exists, and deleting the domain deletes the credential with it. So this is the field to key off when `name` is null -- fetch `GET /domains/{domain}` with it."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "**null means the domain relation was NOT LOADED for this response, so its name is unknown to us here** -- it does NOT mean the credential has no domain, which is impossible, and it is not an empty name. Only `GET /smtp-credentials` eager-loads the relation; create, update, rotate, revoke, enable and the allowlist update all build their response from the credential row alone and report null. That asymmetry is a bug on our side, recorded in the report and not yet fixed -- null is the honest reading of it rather than a cover for it. `domain.id` is correct in every response, so resolve the name from that, or re-read the credential from the list endpoint."
                                                                }
                                                            }
                                                        },
                                                        "ip_allowlist": {
                                                            "type": "object",
                                                            "description": "Enforced by the mail server at AUTH time, not by this API. `enabled: false` with a populated list is a configured allowlist that is currently off, not a contradiction.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "addresses": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "IPv4/IPv6 addresses or CIDR ranges."
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "Per-credential OVERRIDES of your organization's sending tier. These mirror the cap the mail server holds for this credential and are written when it is created or updated through this API; enforcement reads the mail server's own columns, never these.",
                                                            "properties": {
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per hour. **null means NONE -- no per-credential override is set. It does not mean unlimited**, and it does not mean the credential may send nothing: your organization's tier still applies underneath, and it is the thing actually enforced. A client that reads null as \"no cap\" and removes its own throttle is the misreading this wording exists to prevent."
                                                                },
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per day. null means NONE -- no per-credential override, exactly as for `hourly`, and not unlimited."
                                                                }
                                                            }
                                                        },
                                                        "tracking_enabled": {
                                                            "type": "boolean",
                                                            "description": "Whether open and click tracking is injected into HTML sent with this credential."
                                                        },
                                                        "last_used_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC, and **this field is a MIRROR, not a meter** -- read the null accordingly. Nothing in this API writes it: SMTP AUTH happens on the mail server, and an hourly reconcile copies the timestamp across. So null has two readings and you cannot tell them apart from here. Usually it is NONE -- the mail server has never seen this credential authenticate. But it is UNKNOWN whenever the mirror has not caught up: a credential that has not finished provisioning is never asked about at all, and a credential the mail server was unreachable for is skipped until the next hourly run. **A populated value can be up to an hour behind**, and the sync only ever copies a non-null timestamp across, so it never reverts to null once set. Treat null as \"no evidence of use yet\" rather than as proof a credential is idle, and do not revoke on it alone. For a figure read from the mail server at request time, call `GET /smtp-credentials/{credential}/usage`."
                                                        },
                                                        "expires_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means the credential does not expire** -- NONE, no expiry is set, which is the default. **Do not read null as \"expired\"** and do not read it as unknown: a client that treats a null date as a past one will stop sending with a credential that works. Expiry is enforced by the mail server at AUTH time, and `state` already reflects what our mirror knows about it."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "ISO 8601 UTC."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteSmtpCredentialsCredential",
                "summary": "Delete a smtp credential",
                "tags": [
                    "SMTP credentials"
                ],
                "x-required-scope": "smtp:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "credential",
                        "in": "path",
                        "required": true,
                        "description": "The credential identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No body. The credential is scheduled for teardown on the mail server and stops authenticating; until the deprovision completes it is still listed with `state: \"deleting\"`."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/smtp-credentials/{credential}/rotate": {
            "post": {
                "operationId": "postSmtpCredentialsCredentialRotate",
                "summary": "Rotate a smtp credential",
                "tags": [
                    "SMTP credentials"
                ],
                "x-required-scope": "smtp:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "credential",
                        "in": "path",
                        "required": true,
                        "description": "The credential identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "smtp_credential"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the credential."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Your label for it. Not used in authentication. Never null: `smtp_credentials.name` is NOT NULL and creation requires it."
                                                        },
                                                        "username": {
                                                            "type": "string",
                                                            "description": "The SMTP AUTH username, and the credential's public identity: it is what you configure in your mail library and what delivery events are attributed to. Safe to log. Never null: the column is NOT NULL and unique, and the mail server assigns it at creation -- a credential cannot exist without one."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "revoked",
                                                                "pending_review",
                                                                "provisioning",
                                                                "failed",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first. `deleting` and `failed` beat everything: a credential being torn down cannot authenticate however active it looks. `pending_review` is a marketing-stream credential awaiting approval -- provisioned, but refused at AUTH time until it is reviewed. Only `active` can send."
                                                        },
                                                        "stream": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transactional",
                                                                "marketing"
                                                            ],
                                                            "description": "Which lane mail sent with this credential is treated as. The stream decides reputation handling and marketing gating; it is not a label."
                                                        },
                                                        "domain": {
                                                            "type": "object",
                                                            "description": "The one domain this credential may send as. Always present, and `id` is always populated -- it is only `name` that some responses cannot fill.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string",
                                                                    "description": "**Never null.** A credential cannot exist without a domain: `smtp_credentials.domain_id` is a NOT NULL foreign key, creation requires a `domain_id` that exists, and deleting the domain deletes the credential with it. So this is the field to key off when `name` is null -- fetch `GET /domains/{domain}` with it."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "**null means the domain relation was NOT LOADED for this response, so its name is unknown to us here** -- it does NOT mean the credential has no domain, which is impossible, and it is not an empty name. Only `GET /smtp-credentials` eager-loads the relation; create, update, rotate, revoke, enable and the allowlist update all build their response from the credential row alone and report null. That asymmetry is a bug on our side, recorded in the report and not yet fixed -- null is the honest reading of it rather than a cover for it. `domain.id` is correct in every response, so resolve the name from that, or re-read the credential from the list endpoint."
                                                                }
                                                            }
                                                        },
                                                        "ip_allowlist": {
                                                            "type": "object",
                                                            "description": "Enforced by the mail server at AUTH time, not by this API. `enabled: false` with a populated list is a configured allowlist that is currently off, not a contradiction.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "addresses": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "IPv4/IPv6 addresses or CIDR ranges."
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "Per-credential OVERRIDES of your organization's sending tier. These mirror the cap the mail server holds for this credential and are written when it is created or updated through this API; enforcement reads the mail server's own columns, never these.",
                                                            "properties": {
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per hour. **null means NONE -- no per-credential override is set. It does not mean unlimited**, and it does not mean the credential may send nothing: your organization's tier still applies underneath, and it is the thing actually enforced. A client that reads null as \"no cap\" and removes its own throttle is the misreading this wording exists to prevent."
                                                                },
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per day. null means NONE -- no per-credential override, exactly as for `hourly`, and not unlimited."
                                                                }
                                                            }
                                                        },
                                                        "tracking_enabled": {
                                                            "type": "boolean",
                                                            "description": "Whether open and click tracking is injected into HTML sent with this credential."
                                                        },
                                                        "last_used_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC, and **this field is a MIRROR, not a meter** -- read the null accordingly. Nothing in this API writes it: SMTP AUTH happens on the mail server, and an hourly reconcile copies the timestamp across. So null has two readings and you cannot tell them apart from here. Usually it is NONE -- the mail server has never seen this credential authenticate. But it is UNKNOWN whenever the mirror has not caught up: a credential that has not finished provisioning is never asked about at all, and a credential the mail server was unreachable for is skipped until the next hourly run. **A populated value can be up to an hour behind**, and the sync only ever copies a non-null timestamp across, so it never reverts to null once set. Treat null as \"no evidence of use yet\" rather than as proof a credential is idle, and do not revoke on it alone. For a figure read from the mail server at request time, call `GET /smtp-credentials/{credential}/usage`."
                                                        },
                                                        "expires_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means the credential does not expire** -- NONE, no expiry is set, which is the default. **Do not read null as \"expired\"** and do not read it as unknown: a client that treats a null date as a past one will stop sending with a credential that works. Expiry is enforced by the mail server at AUTH time, and `state` already reflects what our mirror knows about it."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "ISO 8601 UTC."
                                                        },
                                                        "password": {
                                                            "type": "string",
                                                            "description": "**Returned once, when the credential is created, and once more each time it is rotated. Never on a read, and it cannot be retrieved again.** It exists only in the mail server's create and rotate responses and is stored nowhere in this API, so nobody -- including Mailyte -- can read it back. Store it when you receive it; if you lose it, rotate rather than recreate. The key is ABSENT rather than null on every other response: `null` would say this credential has no password, which is never true."
                                                        },
                                                        "smtp": {
                                                            "type": "object",
                                                            "description": "Where to send with it, returned **on create only** so a client can be configured from a single response. **The whole object is ABSENT, not null, on every other operation** -- including rotate, which mints a new password but does not repeat the host and port. Do not infer it from the presence of `password`. When it is present both members are always populated, so neither is nullable; the submission endpoint is the same for every credential and does not vary by organization, so it is safe to read once and keep.",
                                                            "properties": {
                                                                "host": {
                                                                    "type": "string",
                                                                    "description": "SMTP submission host."
                                                                },
                                                                "port": {
                                                                    "type": "integer",
                                                                    "description": "SMTP submission port."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/smtp-credentials/{credential}/revoke": {
            "post": {
                "operationId": "postSmtpCredentialsCredentialRevoke",
                "summary": "Revoke a smtp credential",
                "tags": [
                    "SMTP credentials"
                ],
                "x-required-scope": "smtp:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "credential",
                        "in": "path",
                        "required": true,
                        "description": "The credential identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "smtp_credential"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the credential."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Your label for it. Not used in authentication. Never null: `smtp_credentials.name` is NOT NULL and creation requires it."
                                                        },
                                                        "username": {
                                                            "type": "string",
                                                            "description": "The SMTP AUTH username, and the credential's public identity: it is what you configure in your mail library and what delivery events are attributed to. Safe to log. Never null: the column is NOT NULL and unique, and the mail server assigns it at creation -- a credential cannot exist without one."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "revoked",
                                                                "pending_review",
                                                                "provisioning",
                                                                "failed",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first. `deleting` and `failed` beat everything: a credential being torn down cannot authenticate however active it looks. `pending_review` is a marketing-stream credential awaiting approval -- provisioned, but refused at AUTH time until it is reviewed. Only `active` can send."
                                                        },
                                                        "stream": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transactional",
                                                                "marketing"
                                                            ],
                                                            "description": "Which lane mail sent with this credential is treated as. The stream decides reputation handling and marketing gating; it is not a label."
                                                        },
                                                        "domain": {
                                                            "type": "object",
                                                            "description": "The one domain this credential may send as. Always present, and `id` is always populated -- it is only `name` that some responses cannot fill.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string",
                                                                    "description": "**Never null.** A credential cannot exist without a domain: `smtp_credentials.domain_id` is a NOT NULL foreign key, creation requires a `domain_id` that exists, and deleting the domain deletes the credential with it. So this is the field to key off when `name` is null -- fetch `GET /domains/{domain}` with it."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "**null means the domain relation was NOT LOADED for this response, so its name is unknown to us here** -- it does NOT mean the credential has no domain, which is impossible, and it is not an empty name. Only `GET /smtp-credentials` eager-loads the relation; create, update, rotate, revoke, enable and the allowlist update all build their response from the credential row alone and report null. That asymmetry is a bug on our side, recorded in the report and not yet fixed -- null is the honest reading of it rather than a cover for it. `domain.id` is correct in every response, so resolve the name from that, or re-read the credential from the list endpoint."
                                                                }
                                                            }
                                                        },
                                                        "ip_allowlist": {
                                                            "type": "object",
                                                            "description": "Enforced by the mail server at AUTH time, not by this API. `enabled: false` with a populated list is a configured allowlist that is currently off, not a contradiction.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "addresses": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "IPv4/IPv6 addresses or CIDR ranges."
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "Per-credential OVERRIDES of your organization's sending tier. These mirror the cap the mail server holds for this credential and are written when it is created or updated through this API; enforcement reads the mail server's own columns, never these.",
                                                            "properties": {
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per hour. **null means NONE -- no per-credential override is set. It does not mean unlimited**, and it does not mean the credential may send nothing: your organization's tier still applies underneath, and it is the thing actually enforced. A client that reads null as \"no cap\" and removes its own throttle is the misreading this wording exists to prevent."
                                                                },
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per day. null means NONE -- no per-credential override, exactly as for `hourly`, and not unlimited."
                                                                }
                                                            }
                                                        },
                                                        "tracking_enabled": {
                                                            "type": "boolean",
                                                            "description": "Whether open and click tracking is injected into HTML sent with this credential."
                                                        },
                                                        "last_used_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC, and **this field is a MIRROR, not a meter** -- read the null accordingly. Nothing in this API writes it: SMTP AUTH happens on the mail server, and an hourly reconcile copies the timestamp across. So null has two readings and you cannot tell them apart from here. Usually it is NONE -- the mail server has never seen this credential authenticate. But it is UNKNOWN whenever the mirror has not caught up: a credential that has not finished provisioning is never asked about at all, and a credential the mail server was unreachable for is skipped until the next hourly run. **A populated value can be up to an hour behind**, and the sync only ever copies a non-null timestamp across, so it never reverts to null once set. Treat null as \"no evidence of use yet\" rather than as proof a credential is idle, and do not revoke on it alone. For a figure read from the mail server at request time, call `GET /smtp-credentials/{credential}/usage`."
                                                        },
                                                        "expires_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means the credential does not expire** -- NONE, no expiry is set, which is the default. **Do not read null as \"expired\"** and do not read it as unknown: a client that treats a null date as a past one will stop sending with a credential that works. Expiry is enforced by the mail server at AUTH time, and `state` already reflects what our mirror knows about it."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "ISO 8601 UTC."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/smtp-credentials/{credential}/enable": {
            "post": {
                "operationId": "postSmtpCredentialsCredentialEnable",
                "summary": "Enable a smtp credential",
                "tags": [
                    "SMTP credentials"
                ],
                "x-required-scope": "smtp:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "credential",
                        "in": "path",
                        "required": true,
                        "description": "The credential identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "smtp_credential"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the credential."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Your label for it. Not used in authentication. Never null: `smtp_credentials.name` is NOT NULL and creation requires it."
                                                        },
                                                        "username": {
                                                            "type": "string",
                                                            "description": "The SMTP AUTH username, and the credential's public identity: it is what you configure in your mail library and what delivery events are attributed to. Safe to log. Never null: the column is NOT NULL and unique, and the mail server assigns it at creation -- a credential cannot exist without one."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "revoked",
                                                                "pending_review",
                                                                "provisioning",
                                                                "failed",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first. `deleting` and `failed` beat everything: a credential being torn down cannot authenticate however active it looks. `pending_review` is a marketing-stream credential awaiting approval -- provisioned, but refused at AUTH time until it is reviewed. Only `active` can send."
                                                        },
                                                        "stream": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transactional",
                                                                "marketing"
                                                            ],
                                                            "description": "Which lane mail sent with this credential is treated as. The stream decides reputation handling and marketing gating; it is not a label."
                                                        },
                                                        "domain": {
                                                            "type": "object",
                                                            "description": "The one domain this credential may send as. Always present, and `id` is always populated -- it is only `name` that some responses cannot fill.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string",
                                                                    "description": "**Never null.** A credential cannot exist without a domain: `smtp_credentials.domain_id` is a NOT NULL foreign key, creation requires a `domain_id` that exists, and deleting the domain deletes the credential with it. So this is the field to key off when `name` is null -- fetch `GET /domains/{domain}` with it."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "**null means the domain relation was NOT LOADED for this response, so its name is unknown to us here** -- it does NOT mean the credential has no domain, which is impossible, and it is not an empty name. Only `GET /smtp-credentials` eager-loads the relation; create, update, rotate, revoke, enable and the allowlist update all build their response from the credential row alone and report null. That asymmetry is a bug on our side, recorded in the report and not yet fixed -- null is the honest reading of it rather than a cover for it. `domain.id` is correct in every response, so resolve the name from that, or re-read the credential from the list endpoint."
                                                                }
                                                            }
                                                        },
                                                        "ip_allowlist": {
                                                            "type": "object",
                                                            "description": "Enforced by the mail server at AUTH time, not by this API. `enabled: false` with a populated list is a configured allowlist that is currently off, not a contradiction.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "addresses": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "IPv4/IPv6 addresses or CIDR ranges."
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "Per-credential OVERRIDES of your organization's sending tier. These mirror the cap the mail server holds for this credential and are written when it is created or updated through this API; enforcement reads the mail server's own columns, never these.",
                                                            "properties": {
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per hour. **null means NONE -- no per-credential override is set. It does not mean unlimited**, and it does not mean the credential may send nothing: your organization's tier still applies underneath, and it is the thing actually enforced. A client that reads null as \"no cap\" and removes its own throttle is the misreading this wording exists to prevent."
                                                                },
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per day. null means NONE -- no per-credential override, exactly as for `hourly`, and not unlimited."
                                                                }
                                                            }
                                                        },
                                                        "tracking_enabled": {
                                                            "type": "boolean",
                                                            "description": "Whether open and click tracking is injected into HTML sent with this credential."
                                                        },
                                                        "last_used_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC, and **this field is a MIRROR, not a meter** -- read the null accordingly. Nothing in this API writes it: SMTP AUTH happens on the mail server, and an hourly reconcile copies the timestamp across. So null has two readings and you cannot tell them apart from here. Usually it is NONE -- the mail server has never seen this credential authenticate. But it is UNKNOWN whenever the mirror has not caught up: a credential that has not finished provisioning is never asked about at all, and a credential the mail server was unreachable for is skipped until the next hourly run. **A populated value can be up to an hour behind**, and the sync only ever copies a non-null timestamp across, so it never reverts to null once set. Treat null as \"no evidence of use yet\" rather than as proof a credential is idle, and do not revoke on it alone. For a figure read from the mail server at request time, call `GET /smtp-credentials/{credential}/usage`."
                                                        },
                                                        "expires_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means the credential does not expire** -- NONE, no expiry is set, which is the default. **Do not read null as \"expired\"** and do not read it as unknown: a client that treats a null date as a past one will stop sending with a credential that works. Expiry is enforced by the mail server at AUTH time, and `state` already reflects what our mirror knows about it."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "ISO 8601 UTC."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/smtp-credentials/{credential}/ip-allowlist": {
            "put": {
                "operationId": "putSmtpCredentialsCredentialIpAllowlist",
                "summary": "Ip Allowlist a smtp credential",
                "tags": [
                    "SMTP credentials"
                ],
                "x-required-scope": "smtp:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "credential",
                        "in": "path",
                        "required": true,
                        "description": "The credential identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "smtp_credential"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the credential."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Your label for it. Not used in authentication. Never null: `smtp_credentials.name` is NOT NULL and creation requires it."
                                                        },
                                                        "username": {
                                                            "type": "string",
                                                            "description": "The SMTP AUTH username, and the credential's public identity: it is what you configure in your mail library and what delivery events are attributed to. Safe to log. Never null: the column is NOT NULL and unique, and the mail server assigns it at creation -- a credential cannot exist without one."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "revoked",
                                                                "pending_review",
                                                                "provisioning",
                                                                "failed",
                                                                "deleting"
                                                            ],
                                                            "description": "The one lifecycle answer, ordered by what stops you first. `deleting` and `failed` beat everything: a credential being torn down cannot authenticate however active it looks. `pending_review` is a marketing-stream credential awaiting approval -- provisioned, but refused at AUTH time until it is reviewed. Only `active` can send."
                                                        },
                                                        "stream": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transactional",
                                                                "marketing"
                                                            ],
                                                            "description": "Which lane mail sent with this credential is treated as. The stream decides reputation handling and marketing gating; it is not a label."
                                                        },
                                                        "domain": {
                                                            "type": "object",
                                                            "description": "The one domain this credential may send as. Always present, and `id` is always populated -- it is only `name` that some responses cannot fill.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string",
                                                                    "description": "**Never null.** A credential cannot exist without a domain: `smtp_credentials.domain_id` is a NOT NULL foreign key, creation requires a `domain_id` that exists, and deleting the domain deletes the credential with it. So this is the field to key off when `name` is null -- fetch `GET /domains/{domain}` with it."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "**null means the domain relation was NOT LOADED for this response, so its name is unknown to us here** -- it does NOT mean the credential has no domain, which is impossible, and it is not an empty name. Only `GET /smtp-credentials` eager-loads the relation; create, update, rotate, revoke, enable and the allowlist update all build their response from the credential row alone and report null. That asymmetry is a bug on our side, recorded in the report and not yet fixed -- null is the honest reading of it rather than a cover for it. `domain.id` is correct in every response, so resolve the name from that, or re-read the credential from the list endpoint."
                                                                }
                                                            }
                                                        },
                                                        "ip_allowlist": {
                                                            "type": "object",
                                                            "description": "Enforced by the mail server at AUTH time, not by this API. `enabled: false` with a populated list is a configured allowlist that is currently off, not a contradiction.",
                                                            "properties": {
                                                                "enabled": {
                                                                    "type": "boolean"
                                                                },
                                                                "addresses": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "IPv4/IPv6 addresses or CIDR ranges."
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "Per-credential OVERRIDES of your organization's sending tier. These mirror the cap the mail server holds for this credential and are written when it is created or updated through this API; enforcement reads the mail server's own columns, never these.",
                                                            "properties": {
                                                                "hourly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per hour. **null means NONE -- no per-credential override is set. It does not mean unlimited**, and it does not mean the credential may send nothing: your organization's tier still applies underneath, and it is the thing actually enforced. A client that reads null as \"no cap\" and removes its own throttle is the misreading this wording exists to prevent."
                                                                },
                                                                "daily": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients per day. null means NONE -- no per-credential override, exactly as for `hourly`, and not unlimited."
                                                                }
                                                            }
                                                        },
                                                        "tracking_enabled": {
                                                            "type": "boolean",
                                                            "description": "Whether open and click tracking is injected into HTML sent with this credential."
                                                        },
                                                        "last_used_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC, and **this field is a MIRROR, not a meter** -- read the null accordingly. Nothing in this API writes it: SMTP AUTH happens on the mail server, and an hourly reconcile copies the timestamp across. So null has two readings and you cannot tell them apart from here. Usually it is NONE -- the mail server has never seen this credential authenticate. But it is UNKNOWN whenever the mirror has not caught up: a credential that has not finished provisioning is never asked about at all, and a credential the mail server was unreachable for is skipped until the next hourly run. **A populated value can be up to an hour behind**, and the sync only ever copies a non-null timestamp across, so it never reverts to null once set. Treat null as \"no evidence of use yet\" rather than as proof a credential is idle, and do not revoke on it alone. For a figure read from the mail server at request time, call `GET /smtp-credentials/{credential}/usage`."
                                                        },
                                                        "expires_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means the credential does not expire** -- NONE, no expiry is set, which is the default. **Do not read null as \"expired\"** and do not read it as unknown: a client that treats a null date as a past one will stop sending with a credential that works. Expiry is enforced by the mail server at AUTH time, and `state` already reflects what our mirror knows about it."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "ISO 8601 UTC."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/smtp-credentials/{credential}/usage": {
            "get": {
                "operationId": "getSmtpCredentialsCredentialUsage",
                "summary": "Usage a smtp credential",
                "tags": [
                    "SMTP credentials"
                ],
                "x-required-scope": "smtp:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "credential",
                        "in": "path",
                        "required": true,
                        "description": "The credential identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "smtp_credential_usage"
                                                            ]
                                                        },
                                                        "window": {
                                                            "type": "object",
                                                            "description": "The period these counts cover, stated in full so you do not have to infer the end from the start.",
                                                            "properties": {
                                                                "days": {
                                                                    "type": "integer",
                                                                    "description": "Length of the window in days."
                                                                },
                                                                "since": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "ISO 8601 UTC, normalised here: the mail server reports this without a timezone, which a naive parser reads as local time. **null means UNKNOWN -- there is no window, because the mail server was never asked.** That is the `counted: false` case: an unprovisioned credential is answered locally and the local answer has no start date to give. It does not mean \"since the beginning of time\", and it is not an open range you may substitute one for. `days` still reports the length you requested even then, so `days` being populated is no evidence that a window was actually measured -- `since` and `counted` are."
                                                                },
                                                                "until": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "description": "ISO 8601 UTC. The moment the counts were computed against."
                                                                }
                                                            }
                                                        },
                                                        "counted": {
                                                            "type": "boolean",
                                                            "description": "Whether the counts below mean anything. **false when the credential is not provisioned on the mail server**, in which case every count is null rather than zero -- it has never sent, which is not the same as having sent and delivered nothing. Read the true case narrowly: `counted: true` says the mail server was asked and answered, not that every count came back populated. A null count still means unknown even here."
                                                        },
                                                        "total": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "Messages attempted with this credential. Credential-scoped. **null means UNKNOWN, not zero** -- we did not get a number, rather than getting the number nought. Zero is a real answer and is returned as `0`. Two things produce the null: `counted: false`, meaning the credential is not provisioned on the mail server so it was never asked; or the mail server answering without this particular field, which is rare and is still not a licence to read it as 0. Never sum or average across a null -- an unknown treated as zero is how a bill gets computed from a meter nobody read."
                                                        },
                                                        "delivered": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "Accepted by the receiving server. Credential-scoped. **null means UNKNOWN, not zero** -- we did not get a number, rather than getting the number nought. Zero is a real answer and is returned as `0`. Two things produce the null: `counted: false`, meaning the credential is not provisioned on the mail server so it was never asked; or the mail server answering without this particular field, which is rare and is still not a licence to read it as 0. Never sum or average across a null -- an unknown treated as zero is how a bill gets computed from a meter nobody read."
                                                        },
                                                        "bounced": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "Permanently rejected. Credential-scoped. **null means UNKNOWN, not zero** -- we did not get a number, rather than getting the number nought. Zero is a real answer and is returned as `0`. Two things produce the null: `counted: false`, meaning the credential is not provisioned on the mail server so it was never asked; or the mail server answering without this particular field, which is rare and is still not a licence to read it as 0. Never sum or average across a null -- an unknown treated as zero is how a bill gets computed from a meter nobody read."
                                                        },
                                                        "deferred": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "Temporarily rejected and retried. Credential-scoped. **null means UNKNOWN, not zero** -- we did not get a number, rather than getting the number nought. Zero is a real answer and is returned as `0`. Two things produce the null: `counted: false`, meaning the credential is not provisioned on the mail server so it was never asked; or the mail server answering without this particular field, which is rare and is still not a licence to read it as 0. Never sum or average across a null -- an unknown treated as zero is how a bill gets computed from a meter nobody read."
                                                        },
                                                        "rejected": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "Refused by us before submission. Credential-scoped. **null means UNKNOWN, not zero** -- we did not get a number, rather than getting the number nought. Zero is a real answer and is returned as `0`. Two things produce the null: `counted: false`, meaning the credential is not provisioned on the mail server so it was never asked; or the mail server answering without this particular field, which is rare and is still not a licence to read it as 0. Never sum or average across a null -- an unknown treated as zero is how a bill gets computed from a meter nobody read."
                                                        },
                                                        "last_used_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means the mail server has no record of this credential ever authenticating** -- NONE, and lifetime, not \"unused during this window\". Unlike the `last_used_at` on the credential itself, this one is read from the mail server at request time rather than from an hourly mirror, so it is the fresher of the two and the one to trust when they disagree. The one exception is `counted: false`: the mail server was never asked, so null there is unknown rather than never."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-logs": {
            "get": {
                "operationId": "getEmailLogs",
                "summary": "List delivery events",
                "tags": [
                    "Events"
                ],
                "x-required-scope": "events:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "event"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "This event, and the value `GET /email-logs/{event}` takes. The ingest dedupe key that used to be published as `event_id` resolved nowhere and is gone."
                                                                    },
                                                                    "type": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "email.submitted",
                                                                            "email.accepted",
                                                                            "email.delivered",
                                                                            "email.deferred",
                                                                            "email.bounced",
                                                                            "email.dropped",
                                                                            "email.rejected",
                                                                            "email.inbound",
                                                                            "tracking.open",
                                                                            "tracking.click",
                                                                            "tracking.unsubscribe",
                                                                            "delivery.complaint",
                                                                            "spam.reported",
                                                                            "storage.quota.warning",
                                                                            "storage.quota.exceeded",
                                                                            "quota.warning"
                                                                        ],
                                                                        "description": "What happened. Published verbatim, so the value is exactly what `?event_type=` accepts -- a prettier spelling would not match the filter. `email.submitted` is ours, written when we accept a message; the rest arrive from the mail server. A complaint is `delivery.complaint` and has no second name. `quota.warning` is a legacy alias of `storage.quota.warning` that still occurs on older rows. The `storage.*` and `spam.reported` names concern a mailbox rather than one of your messages and share this stream; filter them out with `?event_type=` if you only want delivery."
                                                                    },
                                                                    "recipient": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Who the event concerns. NULL MEANS UNKNOWN -- we could not read the address -- and never that the event had no recipient. Every event WE write fills it from the address you sent to, so this can only be null on an event ingested from the mail server, where the address is resolved best-effort from the webhook payload's `email`, `recipient`, `mailbox` or `to` key: a producer that names it anything else leaves us with nothing to record. Do not treat a null here as a message with no destination, and do not use it to exclude rows from a per-recipient total -- it undercounts."
                                                                    },
                                                                    "detail": {
                                                                        "type": "object",
                                                                        "description": "The extras that only some event types carry. Grouped rather than flat: on a plain delivery all four are null, and flat they read as four missing fields instead of one absent category.",
                                                                        "properties": {
                                                                            "ip_address": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "Who opened or clicked. Null on everything else."
                                                                            },
                                                                            "user_agent": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The client that opened or clicked, as it identified itself. NULL MEANS NONE: the event reached us carrying no user agent, which is ordinary -- an image proxy or a privacy-preserving client sends none, and every event type other than `tracking.open` and `tracking.click` has no agent to carry. It is NOT a field we failed to read and not one we withhold from a list: this is the whole of what arrived. Null here beside a non-null `ip_address` is the normal shape of an open, not a partial record."
                                                                            },
                                                                            "url": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The link that was clicked. Null unless `type` is `tracking.click`. This is where a click's target lives -- the detail endpoint's old `clicked_links` array is gone."
                                                                            },
                                                                            "reason": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "Why a bounce bounced or a drop dropped, as the producer worded it. Free text, not an enum: it comes from the receiving mail server. NULL MEANS NONE -- nothing went wrong with this event, so there is no reason to give. A delivery, an open and a click all read null here and that is the success case, not a missing explanation. On a `email.bounced`, `email.dropped` or `email.deferred` event a null is worth noticing: the producer sent us no wording, and there is nowhere else to recover it from."
                                                                            }
                                                                        }
                                                                    },
                                                                    "message": {
                                                                        "type": "object",
                                                                        "description": "The message this event is about. Byte-identical in shape to `GET /email-logs/{event}` and `GET /email-logs/messages/{id}`, minus the body -- a page of events is not a page of message bodies. ITS CONTENT FIELDS ARE READ OFF THIS ROW'S OWN PAYLOAD, and only an `email.submitted` row carries content, so on a delivered/opened/clicked/dropped row `subject`, `from` and `tags` are null -- NOT INCLUDED, not absent from the message. `GET /email-logs/{event}` resolves the submission and returns them. `id` and `message_id` are real on every row.",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The opaque handle for the message: a BARE ULID, no host and no angle brackets. It is the value `GET /email-logs/messages/{id}` takes. It is NOT the Message-ID -- `message_id` below is a different string for the same message, and the two endpoints do not accept each other's. NULL WOULD MEAN UNKNOWN, and it is not a case you have to code for: this is `COALESCE(message_key, id)`, so an event that carries no message key falls back to its own row id and a persisted event always has one. If you ever do see null we could not identify the message at all, and there is no timeline to fetch -- it never means \"this message has no handle\"."
                                                                            },
                                                                            "message_id": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The RFC 5322 Message-ID, ANGLE BRACKETS INCLUDED -- `<01JBT8XQ2M...@example.com>`. This is the exact header that went out on the wire, so it is the string in the recipient's headers and in every bounce and DSN about the message, and the one `GET /domains/{domain}/messages/{messageId}` accepts (percent-encode it in the path). Handing `id` to the archive, or this to `/email-logs/messages/{id}`, returns 404 -- they are two identifiers doing two jobs. NULL MEANS NONE: the message genuinely never carried a `Message-ID:` header, which is normal for an `email.dropped` event -- we refused it before anything was minted, so there is no header to report and there never will be. It is not a failed lookup and not a withheld value, and a value is never fabricated to fill the field. (This resource did fabricate one on its first run against real data, publishing `<some-row-id@domain>` from the coalesced handle; the un-coalesced key exists to keep the two apart.)"
                                                                            },
                                                                            "subject": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The subject of the original submission. What null means depends on which endpoint you are reading -- see the note on this block. On a list row that is not the submission it is NOT INCLUDED: we hold the subject, this row just is not where it lives, and `GET /email-logs/{event}` or `GET /email-logs/messages/{id}` returns it. Where the submission IS the source, null means NONE -- no submitted event was ever recorded for this message, because every event we have for it arrived by webhook."
                                                                            },
                                                                            "from": {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "email": {
                                                                                        "type": "string",
                                                                                        "nullable": true,
                                                                                        "description": "The sending address. Same rule as `subject`: NOT INCLUDED on a list row that is not the submission -- fetch the event or the timeline -- and NONE where the submission is the source and no submitted event was ever recorded. Read on its own it is also the one honest source of the message's domain; the `domain` field that used to sit beside it was a second copy that could disagree."
                                                                                    },
                                                                                    "name": {
                                                                                        "type": "string",
                                                                                        "nullable": true,
                                                                                        "description": "The sender's display name. Null is NONE where the submission is the source -- the message was sent without one, which is common -- and NOT INCLUDED on a list row that is not the submission, exactly as `from.email` beside it."
                                                                                    }
                                                                                }
                                                                            },
                                                                            "tags": {
                                                                                "type": "array",
                                                                                "nullable": true,
                                                                                "items": {
                                                                                    "type": "string"
                                                                                },
                                                                                "description": "Your own labels, as supplied at send time. THE EMPTY ARRAY AND THE NULL ARE DIFFERENT ANSWERS AND BOTH ARE DELIBERATE. `[]` is NONE and a real answer: this message was submitted with no tags. `null` is NOT INCLUDED: this response was built from an event that is not the submission -- a delivery, an open, a click, a drop -- so we are not telling you what the tags were, and they may well be non-empty. Until 2026-09-18 both cases published `[]`, so a list row flatly denied tags that `GET /email-logs/{event}` returned for the same event. Do not read `[]` as \"untagged\" without checking you are on an endpoint that reads the submission. Not to be confused with a template's `variables`, which this section used to call `tags` too."
                                                                            },
                                                                            "metadata": {
                                                                                "type": "object",
                                                                                "nullable": true,
                                                                                "additionalProperties": {
                                                                                    "type": "string"
                                                                                },
                                                                                "description": "The metadata you set at send time, returned unchanged and never rendered into the message. This is what makes an event correlatable to your own record -- put your order id here and it comes back on every delivery, open and bounce for this message, so you do not have to store our `message_id` against your row first. NOT to be confused with `variables`, which ARE substituted into the subject and bodies and never appear here. `{}` is NONE -- the submission carried no metadata. `null` is NOT INCLUDED -- this event is not the submission, so we are not telling you what it was."
                                                                            }
                                                                        }
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When WE RECORDED the event, which for an ingested webhook is not necessarily when the thing happened. Named `created_at` rather than `occurred_at` because a name promising otherwise is one we cannot keep. NULL WOULD MEAN UNKNOWN and is not a case to code for: the column is `NOT NULL DEFAULT current_timestamp()`, so every stored event has one. It would never mean the event has not happened yet -- there is no such event."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Every event recorded for your organization's mail: accepted, delivered, deferred,\nbounced, complained, opened, clicked, dropped.\n\nPolling this is the simple way to follow a send. Receiving\n[webhooks](/developer/webhooks) is the better one \u2014 it costs you no requests and tells\nyou sooner.\n\n**Opens and clicks are not reliable, by nature.** Open tracking depends on a remote\nimage loading, which privacy proxies fetch on the recipient's behalf and many clients\nblock entirely. Treat them as a weak signal about a population, never as proof about a\nperson."
            }
        },
        "/api/v1/email-logs/messages": {
            "get": {
                "operationId": "getEmailLogsMessages",
                "summary": "Messages (email log)",
                "tags": [
                    "Events"
                ],
                "x-required-scope": "events:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "message"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The opaque handle, and the value `GET /email-logs/messages/{id}` takes. A bare local part or -- for a message that never carried a Message-ID -- a row id; either way it resolves. Not the Message-ID: see `message_id`."
                                                                    },
                                                                    "message_id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The RFC 5322 Message-ID, angle brackets included, for `GET /domains/{domain}/messages/{messageId}`. NULL MEANS THIS MESSAGE NEVER CARRIED THE HEADER -- it is not a missing lookup, and `id` above is deliberately not published here in its place."
                                                                    },
                                                                    "subject": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "NULL MEANS NONE, and on this endpoint that is a strong statement rather than a list omission: the aggregate takes the subject from EVERY event in the group, not just one, so a null means no event we hold for this message carried a subject at all -- the message is known to us only from webhooks and we never saw its submission. Contrast `GET /email-logs`, where a null subject usually just means that ROW is not the submission; here there is no other row to go and look at."
                                                                    },
                                                                    "from": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "email": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "NULL MEANS NONE, on the same terms as `subject`: the aggregate reads `from` and then `sender` across every event in the group, so null means not one of them named a sender. It is not a relation we failed to join and not a value withheld from the list -- fetching the message will not fill it in."
                                                                            },
                                                                            "name": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "NULL MEANS NONE: the display name the message was sent with, read from the submission payload by the same aggregate that reads `subject` and `email`. Null means this sender has no name set, or the group holds no submission event to read one from -- not that the value was withheld. It used to be hardcoded null on every row, which claimed every message went out as a bare address."
                                                                            }
                                                                        }
                                                                    },
                                                                    "recipient": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The one address this message was sent to -- a grouped row is one recipient's copy, so a batch appears as many rows. NULL MEANS UNKNOWN: the aggregate takes the recipient across every event in the group, so null means not one of them recorded an address. Every event we write fills it in, so this only happens on a message known to us purely from ingested webhooks whose payloads named the address under a key we do not read. Never read it as a message with no destination."
                                                                    },
                                                                    "status": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "submitted",
                                                                            "sent",
                                                                            "delivered",
                                                                            "deferred",
                                                                            "bounced",
                                                                            "rejected",
                                                                            "dropped",
                                                                            "opened",
                                                                            "clicked",
                                                                            "complained",
                                                                            "unsubscribed",
                                                                            "unknown"
                                                                        ],
                                                                        "description": "The message's newest outcome, and a CLOSED set: a value this resource does not recognise is published as `unknown` rather than leaking a new one into the contract. Two of these cannot currently occur -- `sent` and `complained` are derived from `email.sent` and `email.complained`, which no producer emits (a complaint arrives as `delivery.complaint`). They stay in the set because the derivation still names them; treat them as reserved."
                                                                    },
                                                                    "activity": {
                                                                        "type": "object",
                                                                        "description": "Counts over every event recorded for this message.",
                                                                        "properties": {
                                                                            "total": {
                                                                                "type": "integer",
                                                                                "description": "All events, of any type."
                                                                            },
                                                                            "opens": {
                                                                                "type": "integer",
                                                                                "description": "Every `tracking.open`, not unique openers -- one person reopening a message counts each time."
                                                                            },
                                                                            "clicks": {
                                                                                "type": "integer",
                                                                                "description": "Every `tracking.click`, not unique links."
                                                                            },
                                                                            "types": {
                                                                                "type": "array",
                                                                                "items": {
                                                                                    "type": "string"
                                                                                },
                                                                                "description": "The distinct `type` values seen for this message, from the same set as an event's `type`."
                                                                            }
                                                                        }
                                                                    },
                                                                    "first_event_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "ISO 8601 UTC. This came off a MySQL aggregate as `2026-09-17 20:10:54` -- no T, no offset -- which parses in most languages AS LOCAL TIME, silently. NULL WOULD MEAN UNKNOWN and is not a case to code for: it is `MIN(created_at)` over a group that exists only because events exist, and that column is NOT NULL. It can never mean \"nothing has happened yet\" -- such a message would not be a row."
                                                                    },
                                                                    "last_event_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "ISO 8601 UTC. The event `status` was derived from. NULL WOULD MEAN UNKNOWN, on the same terms as `first_event_at`, and is likewise unreachable: a group with no events is not published. A message with one event has this equal to `first_event_at`, which is not a bug."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-logs/messages/{messageKey}": {
            "get": {
                "operationId": "getEmailLogsMessagesMessageKey",
                "summary": "Get a message timeline",
                "tags": [
                    "Events"
                ],
                "x-required-scope": "events:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "messageKey",
                        "in": "path",
                        "required": true,
                        "description": "The message key identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "message"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The opaque handle for the message: a BARE ULID, no host and no angle brackets. It is the value `GET /email-logs/messages/{id}` takes. It is NOT the Message-ID -- `message_id` below is a different string for the same message, and the two endpoints do not accept each other's. NULL WOULD MEAN UNKNOWN, and it is not a case you have to code for: this is `COALESCE(message_key, id)`, so an event that carries no message key falls back to its own row id and a persisted event always has one. If you ever do see null we could not identify the message at all, and there is no timeline to fetch -- it never means \"this message has no handle\"."
                                                        },
                                                        "message_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The RFC 5322 Message-ID, ANGLE BRACKETS INCLUDED -- `<01JBT8XQ2M...@example.com>`. This is the exact header that went out on the wire, so it is the string in the recipient's headers and in every bounce and DSN about the message, and the one `GET /domains/{domain}/messages/{messageId}` accepts (percent-encode it in the path). Handing `id` to the archive, or this to `/email-logs/messages/{id}`, returns 404 -- they are two identifiers doing two jobs. NULL MEANS NONE: the message genuinely never carried a `Message-ID:` header, which is normal for an `email.dropped` event -- we refused it before anything was minted, so there is no header to report and there never will be. It is not a failed lookup and not a withheld value, and a value is never fabricated to fill the field. (This resource did fabricate one on its first run against real data, publishing `<some-row-id@domain>` from the coalesced handle; the un-coalesced key exists to keep the two apart.)"
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The subject of the original submission. What null means depends on which endpoint you are reading -- see the note on this block. On a list row that is not the submission it is NOT INCLUDED: we hold the subject, this row just is not where it lives, and `GET /email-logs/{event}` or `GET /email-logs/messages/{id}` returns it. Where the submission IS the source, null means NONE -- no submitted event was ever recorded for this message, because every event we have for it arrived by webhook."
                                                        },
                                                        "from": {
                                                            "type": "object",
                                                            "properties": {
                                                                "email": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sending address. Same rule as `subject`: NOT INCLUDED on a list row that is not the submission -- fetch the event or the timeline -- and NONE where the submission is the source and no submitted event was ever recorded. Read on its own it is also the one honest source of the message's domain; the `domain` field that used to sit beside it was a second copy that could disagree."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. Null is NONE where the submission is the source -- the message was sent without one, which is common -- and NOT INCLUDED on a list row that is not the submission, exactly as `from.email` beside it."
                                                                }
                                                            }
                                                        },
                                                        "tags": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "string"
                                                            },
                                                            "description": "Your own labels, as supplied at send time. THE EMPTY ARRAY AND THE NULL ARE DIFFERENT ANSWERS AND BOTH ARE DELIBERATE. `[]` is NONE and a real answer: this message was submitted with no tags. `null` is NOT INCLUDED: this response was built from an event that is not the submission -- a delivery, an open, a click, a drop -- so we are not telling you what the tags were, and they may well be non-empty. Until 2026-09-18 both cases published `[]`, so a list row flatly denied tags that `GET /email-logs/{event}` returned for the same event. Do not read `[]` as \"untagged\" without checking you are on an endpoint that reads the submission. Not to be confused with a template's `variables`, which this section used to call `tags` too."
                                                        },
                                                        "metadata": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "additionalProperties": {
                                                                "type": "string"
                                                            },
                                                            "description": "The metadata you set at send time, returned unchanged and never rendered into the message. This is what makes an event correlatable to your own record -- put your order id here and it comes back on every delivery, open and bounce for this message, so you do not have to store our `message_id` against your row first. NOT to be confused with `variables`, which ARE substituted into the subject and bodies and never appear here. `{}` is NONE -- the submission carried no metadata. `null` is NOT INCLUDED -- this event is not the submission, so we are not telling you what it was."
                                                        },
                                                        "html": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The rendered HTML body of the ORIGINAL submission, not of the event you asked about -- a click or an open carries no body of its own. NULL MEANS NONE, and this field is only ever published by an endpoint that resolves the submission, so it is never a withheld value: either no submitted event was ever recorded for this message (every event we hold arrived by webhook) or the submission was text-only. `text` beside it tells you which."
                                                        },
                                                        "text": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The plain-text body. NULL MEANS NONE, on the same terms as `html`: no submitted event was recorded, or the submission carried no text part. Note that a normal send cannot produce the second case -- MessageSendService derives a text alternative from the HTML when the caller supplies none -- so null here with a non-null `html` means the row predates that. Spelled `text` on every read in this section; the template WRITE side is the one exception and still takes `plain_text`."
                                                        },
                                                        "recipient": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Who this message went to, taken from the submitted event and failing that from the oldest event we hold. NULL MEANS UNKNOWN -- neither carried an address we could read -- and never that the message had no destination. See an event's own `recipient` for why an ingested event can lack one. This is ONE address: a message here is one recipient's copy, so a batch or a campaign appears as many messages, not as one with many recipients."
                                                        },
                                                        "events": {
                                                            "type": "array",
                                                            "description": "Everything that happened to this message, oldest first. The same object the flat log publishes, so code written for one reads the other -- including `detail.url`, which is where a click's target lives.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "event"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "This event, and the value `GET /email-logs/{event}` takes. The ingest dedupe key that used to be published as `event_id` resolved nowhere and is gone."
                                                                    },
                                                                    "type": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "email.submitted",
                                                                            "email.accepted",
                                                                            "email.delivered",
                                                                            "email.deferred",
                                                                            "email.bounced",
                                                                            "email.dropped",
                                                                            "email.rejected",
                                                                            "email.inbound",
                                                                            "tracking.open",
                                                                            "tracking.click",
                                                                            "tracking.unsubscribe",
                                                                            "delivery.complaint",
                                                                            "spam.reported",
                                                                            "storage.quota.warning",
                                                                            "storage.quota.exceeded",
                                                                            "quota.warning"
                                                                        ],
                                                                        "description": "What happened. Published verbatim, so the value is exactly what `?event_type=` accepts -- a prettier spelling would not match the filter. `email.submitted` is ours, written when we accept a message; the rest arrive from the mail server. A complaint is `delivery.complaint` and has no second name. `quota.warning` is a legacy alias of `storage.quota.warning` that still occurs on older rows. The `storage.*` and `spam.reported` names concern a mailbox rather than one of your messages and share this stream; filter them out with `?event_type=` if you only want delivery."
                                                                    },
                                                                    "recipient": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Who the event concerns. NULL MEANS UNKNOWN -- we could not read the address -- and never that the event had no recipient. Every event WE write fills it from the address you sent to, so this can only be null on an event ingested from the mail server, where the address is resolved best-effort from the webhook payload's `email`, `recipient`, `mailbox` or `to` key: a producer that names it anything else leaves us with nothing to record. Do not treat a null here as a message with no destination, and do not use it to exclude rows from a per-recipient total -- it undercounts."
                                                                    },
                                                                    "detail": {
                                                                        "type": "object",
                                                                        "description": "The extras that only some event types carry. Grouped rather than flat: on a plain delivery all four are null, and flat they read as four missing fields instead of one absent category.",
                                                                        "properties": {
                                                                            "ip_address": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "Who opened or clicked. Null on everything else."
                                                                            },
                                                                            "user_agent": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The client that opened or clicked, as it identified itself. NULL MEANS NONE: the event reached us carrying no user agent, which is ordinary -- an image proxy or a privacy-preserving client sends none, and every event type other than `tracking.open` and `tracking.click` has no agent to carry. It is NOT a field we failed to read and not one we withhold from a list: this is the whole of what arrived. Null here beside a non-null `ip_address` is the normal shape of an open, not a partial record."
                                                                            },
                                                                            "url": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The link that was clicked. Null unless `type` is `tracking.click`. This is where a click's target lives -- the detail endpoint's old `clicked_links` array is gone."
                                                                            },
                                                                            "reason": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "Why a bounce bounced or a drop dropped, as the producer worded it. Free text, not an enum: it comes from the receiving mail server. NULL MEANS NONE -- nothing went wrong with this event, so there is no reason to give. A delivery, an open and a click all read null here and that is the success case, not a missing explanation. On a `email.bounced`, `email.dropped` or `email.deferred` event a null is worth noticing: the producer sent us no wording, and there is nowhere else to recover it from."
                                                                            }
                                                                        }
                                                                    },
                                                                    "message": {
                                                                        "type": "object",
                                                                        "description": "The message this event is about. Byte-identical in shape to `GET /email-logs/{event}` and `GET /email-logs/messages/{id}`, minus the body -- a page of events is not a page of message bodies. ITS CONTENT FIELDS ARE READ OFF THIS ROW'S OWN PAYLOAD, and only an `email.submitted` row carries content, so on a delivered/opened/clicked/dropped row `subject`, `from` and `tags` are null -- NOT INCLUDED, not absent from the message. `GET /email-logs/{event}` resolves the submission and returns them. `id` and `message_id` are real on every row.",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The opaque handle for the message: a BARE ULID, no host and no angle brackets. It is the value `GET /email-logs/messages/{id}` takes. It is NOT the Message-ID -- `message_id` below is a different string for the same message, and the two endpoints do not accept each other's. NULL WOULD MEAN UNKNOWN, and it is not a case you have to code for: this is `COALESCE(message_key, id)`, so an event that carries no message key falls back to its own row id and a persisted event always has one. If you ever do see null we could not identify the message at all, and there is no timeline to fetch -- it never means \"this message has no handle\"."
                                                                            },
                                                                            "message_id": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The RFC 5322 Message-ID, ANGLE BRACKETS INCLUDED -- `<01JBT8XQ2M...@example.com>`. This is the exact header that went out on the wire, so it is the string in the recipient's headers and in every bounce and DSN about the message, and the one `GET /domains/{domain}/messages/{messageId}` accepts (percent-encode it in the path). Handing `id` to the archive, or this to `/email-logs/messages/{id}`, returns 404 -- they are two identifiers doing two jobs. NULL MEANS NONE: the message genuinely never carried a `Message-ID:` header, which is normal for an `email.dropped` event -- we refused it before anything was minted, so there is no header to report and there never will be. It is not a failed lookup and not a withheld value, and a value is never fabricated to fill the field. (This resource did fabricate one on its first run against real data, publishing `<some-row-id@domain>` from the coalesced handle; the un-coalesced key exists to keep the two apart.)"
                                                                            },
                                                                            "subject": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The subject of the original submission. What null means depends on which endpoint you are reading -- see the note on this block. On a list row that is not the submission it is NOT INCLUDED: we hold the subject, this row just is not where it lives, and `GET /email-logs/{event}` or `GET /email-logs/messages/{id}` returns it. Where the submission IS the source, null means NONE -- no submitted event was ever recorded for this message, because every event we have for it arrived by webhook."
                                                                            },
                                                                            "from": {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "email": {
                                                                                        "type": "string",
                                                                                        "nullable": true,
                                                                                        "description": "The sending address. Same rule as `subject`: NOT INCLUDED on a list row that is not the submission -- fetch the event or the timeline -- and NONE where the submission is the source and no submitted event was ever recorded. Read on its own it is also the one honest source of the message's domain; the `domain` field that used to sit beside it was a second copy that could disagree."
                                                                                    },
                                                                                    "name": {
                                                                                        "type": "string",
                                                                                        "nullable": true,
                                                                                        "description": "The sender's display name. Null is NONE where the submission is the source -- the message was sent without one, which is common -- and NOT INCLUDED on a list row that is not the submission, exactly as `from.email` beside it."
                                                                                    }
                                                                                }
                                                                            },
                                                                            "tags": {
                                                                                "type": "array",
                                                                                "nullable": true,
                                                                                "items": {
                                                                                    "type": "string"
                                                                                },
                                                                                "description": "Your own labels, as supplied at send time. THE EMPTY ARRAY AND THE NULL ARE DIFFERENT ANSWERS AND BOTH ARE DELIBERATE. `[]` is NONE and a real answer: this message was submitted with no tags. `null` is NOT INCLUDED: this response was built from an event that is not the submission -- a delivery, an open, a click, a drop -- so we are not telling you what the tags were, and they may well be non-empty. Until 2026-09-18 both cases published `[]`, so a list row flatly denied tags that `GET /email-logs/{event}` returned for the same event. Do not read `[]` as \"untagged\" without checking you are on an endpoint that reads the submission. Not to be confused with a template's `variables`, which this section used to call `tags` too."
                                                                            },
                                                                            "metadata": {
                                                                                "type": "object",
                                                                                "nullable": true,
                                                                                "additionalProperties": {
                                                                                    "type": "string"
                                                                                },
                                                                                "description": "The metadata you set at send time, returned unchanged and never rendered into the message. This is what makes an event correlatable to your own record -- put your order id here and it comes back on every delivery, open and bounce for this message, so you do not have to store our `message_id` against your row first. NOT to be confused with `variables`, which ARE substituted into the subject and bodies and never appear here. `{}` is NONE -- the submission carried no metadata. `null` is NOT INCLUDED -- this event is not the submission, so we are not telling you what it was."
                                                                            }
                                                                        }
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When WE RECORDED the event, which for an ingested webhook is not necessarily when the thing happened. Named `created_at` rather than `occurred_at` because a name promising otherwise is one we cannot keep. NULL WOULD MEAN UNKNOWN and is not a case to code for: the column is `NOT NULL DEFAULT current_timestamp()`, so every stored event has one. It would never mean the event has not happened yet -- there is no such event."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Every event for one message, oldest first \u2014 the whole story of a single send in one call."
            }
        },
        "/api/v1/email-logs/{event}": {
            "get": {
                "operationId": "getEmailLogsEvent",
                "summary": "Retrieve a email log",
                "tags": [
                    "Events"
                ],
                "x-required-scope": "events:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "event",
                        "in": "path",
                        "required": true,
                        "description": "The event identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "event"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "This event."
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "email.submitted",
                                                                "email.accepted",
                                                                "email.delivered",
                                                                "email.deferred",
                                                                "email.bounced",
                                                                "email.dropped",
                                                                "email.rejected",
                                                                "email.inbound",
                                                                "tracking.open",
                                                                "tracking.click",
                                                                "tracking.unsubscribe",
                                                                "delivery.complaint",
                                                                "spam.reported",
                                                                "storage.quota.warning",
                                                                "storage.quota.exceeded",
                                                                "quota.warning"
                                                            ],
                                                            "description": "What happened. Published verbatim, so the value is exactly what `?event_type=` accepts -- a prettier spelling would not match the filter. `email.submitted` is ours, written when we accept a message; the rest arrive from the mail server. A complaint is `delivery.complaint` and has no second name. `quota.warning` is a legacy alias of `storage.quota.warning` that still occurs on older rows. The `storage.*` and `spam.reported` names concern a mailbox rather than one of your messages and share this stream; filter them out with `?event_type=` if you only want delivery."
                                                        },
                                                        "recipient": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Who the event concerns. NULL MEANS UNKNOWN -- we could not read the address -- and never that the event had no recipient. Every event WE write fills it from the address you sent to, so this can only be null on an event ingested from the mail server, where the address is resolved best-effort from the webhook payload's `email`, `recipient`, `mailbox` or `to` key: a producer that names it anything else leaves us with nothing to record. Do not treat a null here as a message with no destination, and do not use it to exclude rows from a per-recipient total -- it undercounts."
                                                        },
                                                        "detail": {
                                                            "type": "object",
                                                            "description": "The extras that only some event types carry. Grouped rather than flat: on a plain delivery all four are null, and flat they read as four missing fields instead of one absent category.",
                                                            "properties": {
                                                                "ip_address": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Who opened or clicked. Null on everything else."
                                                                },
                                                                "user_agent": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The client that opened or clicked, as it identified itself. NULL MEANS NONE: the event reached us carrying no user agent, which is ordinary -- an image proxy or a privacy-preserving client sends none, and every event type other than `tracking.open` and `tracking.click` has no agent to carry. It is NOT a field we failed to read and not one we withhold from a list: this is the whole of what arrived. Null here beside a non-null `ip_address` is the normal shape of an open, not a partial record."
                                                                },
                                                                "url": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The link that was clicked. Null unless `type` is `tracking.click`. This is where a click's target lives -- the detail endpoint's old `clicked_links` array is gone."
                                                                },
                                                                "reason": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why a bounce bounced or a drop dropped, as the producer worded it. Free text, not an enum: it comes from the receiving mail server. NULL MEANS NONE -- nothing went wrong with this event, so there is no reason to give. A delivery, an open and a click all read null here and that is the success case, not a missing explanation. On a `email.bounced`, `email.dropped` or `email.deferred` event a null is worth noticing: the producer sent us no wording, and there is nowhere else to recover it from."
                                                                }
                                                            }
                                                        },
                                                        "message": {
                                                            "type": "object",
                                                            "description": "The message this event is about, WITH its body -- the reason people open this endpoint. The body is the original submission's, not this row's: a click or an open carries no content of its own. `message.id` is the pointer to the full timeline, which is why this response no longer repeats it as `history` and `clicked_links`. THIS ENDPOINT RESOLVES THE SUBMISSION, so `subject`, `from` and `tags` are the message's real values here and null means the submission genuinely had none -- unlike `GET /email-logs`, where the same fields are read off each row's own payload and are null on any row that is not the submission.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The opaque handle for the message: a BARE ULID, no host and no angle brackets. It is the value `GET /email-logs/messages/{id}` takes. It is NOT the Message-ID -- `message_id` below is a different string for the same message, and the two endpoints do not accept each other's. NULL WOULD MEAN UNKNOWN, and it is not a case you have to code for: this is `COALESCE(message_key, id)`, so an event that carries no message key falls back to its own row id and a persisted event always has one. If you ever do see null we could not identify the message at all, and there is no timeline to fetch -- it never means \"this message has no handle\"."
                                                                },
                                                                "message_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The RFC 5322 Message-ID, ANGLE BRACKETS INCLUDED -- `<01JBT8XQ2M...@example.com>`. This is the exact header that went out on the wire, so it is the string in the recipient's headers and in every bounce and DSN about the message, and the one `GET /domains/{domain}/messages/{messageId}` accepts (percent-encode it in the path). Handing `id` to the archive, or this to `/email-logs/messages/{id}`, returns 404 -- they are two identifiers doing two jobs. NULL MEANS NONE: the message genuinely never carried a `Message-ID:` header, which is normal for an `email.dropped` event -- we refused it before anything was minted, so there is no header to report and there never will be. It is not a failed lookup and not a withheld value, and a value is never fabricated to fill the field. (This resource did fabricate one on its first run against real data, publishing `<some-row-id@domain>` from the coalesced handle; the un-coalesced key exists to keep the two apart.)"
                                                                },
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject of the original submission. What null means depends on which endpoint you are reading -- see the note on this block. On a list row that is not the submission it is NOT INCLUDED: we hold the subject, this row just is not where it lives, and `GET /email-logs/{event}` or `GET /email-logs/messages/{id}` returns it. Where the submission IS the source, null means NONE -- no submitted event was ever recorded for this message, because every event we have for it arrived by webhook."
                                                                },
                                                                "from": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "email": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "The sending address. Same rule as `subject`: NOT INCLUDED on a list row that is not the submission -- fetch the event or the timeline -- and NONE where the submission is the source and no submitted event was ever recorded. Read on its own it is also the one honest source of the message's domain; the `domain` field that used to sit beside it was a second copy that could disagree."
                                                                        },
                                                                        "name": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "The sender's display name. Null is NONE where the submission is the source -- the message was sent without one, which is common -- and NOT INCLUDED on a list row that is not the submission, exactly as `from.email` beside it."
                                                                        }
                                                                    }
                                                                },
                                                                "tags": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Your own labels, as supplied at send time. THE EMPTY ARRAY AND THE NULL ARE DIFFERENT ANSWERS AND BOTH ARE DELIBERATE. `[]` is NONE and a real answer: this message was submitted with no tags. `null` is NOT INCLUDED: this response was built from an event that is not the submission -- a delivery, an open, a click, a drop -- so we are not telling you what the tags were, and they may well be non-empty. Until 2026-09-18 both cases published `[]`, so a list row flatly denied tags that `GET /email-logs/{event}` returned for the same event. Do not read `[]` as \"untagged\" without checking you are on an endpoint that reads the submission. Not to be confused with a template's `variables`, which this section used to call `tags` too."
                                                                },
                                                                "metadata": {
                                                                    "type": "object",
                                                                    "nullable": true,
                                                                    "additionalProperties": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "The metadata you set at send time, returned unchanged and never rendered into the message. This is what makes an event correlatable to your own record -- put your order id here and it comes back on every delivery, open and bounce for this message, so you do not have to store our `message_id` against your row first. NOT to be confused with `variables`, which ARE substituted into the subject and bodies and never appear here. `{}` is NONE -- the submission carried no metadata. `null` is NOT INCLUDED -- this event is not the submission, so we are not telling you what it was."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The rendered HTML body of the ORIGINAL submission, not of the event you asked about -- a click or an open carries no body of its own. NULL MEANS NONE, and this field is only ever published by an endpoint that resolves the submission, so it is never a withheld value: either no submitted event was ever recorded for this message (every event we hold arrived by webhook) or the submission was text-only. `text` beside it tells you which."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body. NULL MEANS NONE, on the same terms as `html`: no submitted event was recorded, or the submission carried no text part. Note that a normal send cannot produce the second case -- MessageSendService derives a text alternative from the HTML when the caller supplies none -- so null here with a non-null `html` means the row predates that. Spelled `text` on every read in this section; the template WRITE side is the one exception and still takes `plain_text`."
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When WE RECORDED the event, which for an ingested webhook is not necessarily when the thing happened. Named `created_at` rather than `occurred_at` because a name promising otherwise is one we cannot keep. NULL WOULD MEAN UNKNOWN and is not a case to code for: the column is `NOT NULL DEFAULT current_timestamp()`, so every stored event has one. It would never mean the event has not happened yet -- there is no such event."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteEmailLogsEvent",
                "summary": "Delete a delivery event",
                "tags": [
                    "Events"
                ],
                "x-required-scope": "suppressions:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "event",
                        "in": "path",
                        "required": true,
                        "description": "The event identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. The event is erased from the log; the message's other events are untouched, so a timeline can be left with a hole in it."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Removes an event from the log. Requires a write scope: a key issued for reporting must not be able to erase the history it reports on."
            }
        },
        "/api/v1/email-logs/{event}/resend": {
            "post": {
                "operationId": "postEmailLogsEventResend",
                "summary": "Resend a message",
                "tags": [
                    "Events"
                ],
                "x-required-scope": "messages:send",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "event",
                        "in": "path",
                        "required": true,
                        "description": "The event identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "message"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The opaque handle for this submission: a BARE ULID, no host and no angle brackets. `GET /email-logs/messages/{id}` resolves it immediately -- you do not have to wait for a webhook. It is NOT the Message-ID. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx: the send mints this before it records anything, so a response that carries a receipt carries a handle. If you are holding null you are not holding an accepted message."
                                                        },
                                                        "message_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The RFC 5322 Message-ID as it went out on the wire, ANGLE BRACKETS INCLUDED -- `<01JBT8XQ2M...@example.com>`. It is the header your recipient sees and the id `GET /domains/{domain}/messages/{messageId}` takes; percent-encode it in the path. `id` is the bare ULID and the two are not interchangeable: giving `id` to the archive endpoint returns 404, which is precisely what this field used to publish. Null when no sending host could be determined, never a guess."
                                                        },
                                                        "recipient": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The PRIMARY addressee, without any display name. Published as `recipient` rather than `to`, matching every event and message row in this section. It stays a single string now that a message may have several recipients, so code reading it does not change type underneath you -- read `recipients` for the whole set. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx, since `to` is required."
                                                        },
                                                        "recipients": {
                                                            "type": "object",
                                                            "description": "Everyone the message was addressed to. **`bcc` is deliberately absent**: blind recipients are recorded in your delivery log but never echoed on a receipt, which is the one response most likely to be forwarded, logged or shown to a customer.",
                                                            "properties": {
                                                                "to": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "As accepted, including any display name."
                                                                },
                                                                "cc": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Empty when none were given -- NONE, not unknown."
                                                                },
                                                                "count": {
                                                                    "type": "integer",
                                                                    "description": "To plus Cc. Excludes Bcc, which is not published here; the limit of 50 counts all three together."
                                                                }
                                                            }
                                                        },
                                                        "reply_to": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The Reply-To that went out. NULL MEANS NONE was set, in which case replies go to `from`."
                                                        },
                                                        "attachment_count": {
                                                            "type": "integer",
                                                            "description": "How many files were attached. Zero means none were sent, never that we did not look."
                                                        },
                                                        "from": {
                                                            "type": "object",
                                                            "description": "The sender. An object here, and everywhere else a sender appears, so one piece of caller code reads all of them.",
                                                            "properties": {
                                                                "email": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The address this was accepted as, echoed back. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx -- `from` is a required, validated field on the request and the receipt republishes the resolved sender's own address. It is never \"sent from nowhere\"."
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The display name the message was sent with \u2014 the same one that went into the `From:` header, not a lookup done afterwards. NULL MEANS NONE: this sender has no display name set, so the message went out as a bare address. It is not \"unknown\" and it is not withheld \u2014 set a name on the sender and it appears here."
                                                                }
                                                            }
                                                        },
                                                        "subject": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The subject AS RENDERED -- `{{ }}` substituted, the same string that went into the header -- which is why it can differ from what you posted and why it is echoed at all. NULL WOULD MEAN UNKNOWN and cannot happen on a 2xx: the renderer falls back to the empty string, so a subjectless send is published as `\"\"`, never as null. Test for `\"\"`, not for null."
                                                        },
                                                        "submitted_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When we ACCEPTED the message, not when it was delivered. A 200 here means queued; the outcome arrives as a delivery event or a webhook. NULL WOULD MEAN UNKNOWN -- we could not read the timestamp off the recorded submission -- and never that the message is not submitted yet. A 2xx has already written the row, and its timestamp column is `NOT NULL DEFAULT current_timestamp()`, so this is not a case to code for."
                                                        },
                                                        "mode": {
                                                            "type": "string",
                                                            "enum": [
                                                                "live",
                                                                "test"
                                                            ],
                                                            "description": "Whether a real message was sent. `test` means this request was made with a TEST API KEY: it was validated exactly as a live one would be \u2014 the sender had to be verified, the recipients had to not be suppressed, the rate limit applied \u2014 and then nothing was handed to the mail server and nothing was recorded. `id`, `message_id` and `submitted_at` are null for that reason: there is no message to look up. Test mode is a property of the key, not of the request, so it cannot be switched on by a stray parameter in production code."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Submits the stored copy of this message again. Requires `messages:send`, not\n`events:read` \u2014 it puts mail back on the wire.\n\nPass `to` to send it somewhere else. That is the usual reason to resend: the customer\ngave the wrong address, and reconstructing the message by hand to send it to the right\none loses whatever the original actually said.\n\nA redirected resend is not a privileged path \u2014 the new recipient is checked against\nyour suppression list and counted against your rate limit exactly like a fresh send.",
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "to": {
                                        "oneOf": [
                                            {
                                                "type": "string"
                                            },
                                            {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            }
                                        ],
                                        "description": "Send to this address instead of the original recipient. Omit to resend to whoever it went to the first time."
                                    }
                                }
                            },
                            "example": {
                                "to": "corrected@example.com"
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/email-suppressions": {
            "get": {
                "operationId": "getEmailSuppressions",
                "summary": "List suppressed addresses",
                "tags": [
                    "Suppressions"
                ],
                "x-required-scope": "suppressions:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "suppression"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "email": {
                                                                        "type": "string",
                                                                        "description": "The address, or -- when `scope` is `domain` -- the bare domain. Always lower-cased: the send-time check normalises, and a mixed-case row would never match it."
                                                                    },
                                                                    "scope": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "address",
                                                                            "domain"
                                                                        ],
                                                                        "description": "A `domain` rule blocks every recipient at that EXACT domain. Subdomains are separate rules, matching SendGrid and Mailgun, so a rule never blocks more than the string somebody typed."
                                                                    },
                                                                    "applies_to": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "all",
                                                                            "marketing"
                                                                        ],
                                                                        "description": "Which traffic this suppression stops, and a DIFFERENT axis from `scope`. `all` stops everything including transactional mail; `marketing` stops campaigns and leaves receipts, password resets and other transactional mail alone. Derived from `reason`: an unsubscribe is `marketing`, because withdrawing consent to be marketed to has never meant refusing a password reset; a bounce or a complaint is `all`, because a dead or hostile address is a problem for every kind of mail. NOT nullable -- the column is NOT NULL and defaults to `all`, so an unclassified suppression stops everything rather than silently stopping less."
                                                                    },
                                                                    "reason": {
                                                                        "type": "string",
                                                                        "description": "Why this address is blocked. `POST /email-suppressions` accepts only `unsubscribed`, `complained`, `bounced` or `manual`, but this field is NOT closed: `POST /email-suppressions/import` takes any string up to 30 characters and defaults to the literal `import`, so imported rows carry values the single-add endpoint would reject. Do not switch on it exhaustively."
                                                                    },
                                                                    "source": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "manual",
                                                                            "automatic"
                                                                        ],
                                                                        "description": "`manual` is a person or your API call; `automatic` is our bounce and complaint listener. A manual entry is never downgraded to automatic by a later event."
                                                                    },
                                                                    "note": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Your own free text. NULL MEANS NONE -- no note was supplied when the row was written -- and that is the usual case, because only a person adding an entry by hand tends to write one. Nothing we do fills this in: an address suppressed automatically by the bounce and complaint listener has no note and never will, and `reason` is where the machine explanation lives."
                                                                    },
                                                                    "suppressed_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When the address was suppressed, and the ONLY date published here. `created_at`/`updated_at` made three dates for one event and they disagreed -- `updated_at` moves when a later bounce refreshes the row. NULL MEANS UNKNOWN: the column was added after this table already had rows, and although the migration backfilled every one of them from `created_at`, the column is nullable and nothing constrains a future writer to fill it. It never means \"not suppressed\" -- the row existing is what suppresses the address, and a null date does not soften that. Sort on it defensively."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Addresses Mailyte will refuse to send to, and why.\n\nSuppressions are enforced ahead of your own list logic \u2014 removing someone from your\ndatabase does not remove them from here, and adding them back in your database does\nnot resurrect them here. This is what keeps a hard bounce from being retried into a\nreputation problem."
            },
            "post": {
                "operationId": "postEmailSuppressions",
                "summary": "Create a email suppression",
                "tags": [
                    "Suppressions"
                ],
                "x-required-scope": "suppressions:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "suppression"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string"
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "description": "The address, or -- when `scope` is `domain` -- the bare domain. Always lower-cased: the send-time check normalises, and a mixed-case row would never match it."
                                                        },
                                                        "scope": {
                                                            "type": "string",
                                                            "enum": [
                                                                "address",
                                                                "domain"
                                                            ],
                                                            "description": "A `domain` rule blocks every recipient at that EXACT domain. Subdomains are separate rules, matching SendGrid and Mailgun, so a rule never blocks more than the string somebody typed."
                                                        },
                                                        "applies_to": {
                                                            "type": "string",
                                                            "enum": [
                                                                "all",
                                                                "marketing"
                                                            ],
                                                            "description": "Which traffic this suppression stops, and a DIFFERENT axis from `scope`. `all` stops everything including transactional mail; `marketing` stops campaigns and leaves receipts, password resets and other transactional mail alone. Derived from `reason`: an unsubscribe is `marketing`, because withdrawing consent to be marketed to has never meant refusing a password reset; a bounce or a complaint is `all`, because a dead or hostile address is a problem for every kind of mail. NOT nullable -- the column is NOT NULL and defaults to `all`, so an unclassified suppression stops everything rather than silently stopping less."
                                                        },
                                                        "reason": {
                                                            "type": "string",
                                                            "description": "Why this address is blocked. `POST /email-suppressions` accepts only `unsubscribed`, `complained`, `bounced` or `manual`, but this field is NOT closed: `POST /email-suppressions/import` takes any string up to 30 characters and defaults to the literal `import`, so imported rows carry values the single-add endpoint would reject. Do not switch on it exhaustively."
                                                        },
                                                        "source": {
                                                            "type": "string",
                                                            "enum": [
                                                                "manual",
                                                                "automatic"
                                                            ],
                                                            "description": "`manual` is a person or your API call; `automatic` is our bounce and complaint listener. A manual entry is never downgraded to automatic by a later event."
                                                        },
                                                        "note": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Your own free text. NULL MEANS NONE -- no note was supplied when the row was written -- and that is the usual case, because only a person adding an entry by hand tends to write one. Nothing we do fills this in: an address suppressed automatically by the bounce and complaint listener has no note and never will, and `reason` is where the machine explanation lives."
                                                        },
                                                        "suppressed_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the address was suppressed, and the ONLY date published here. `created_at`/`updated_at` made three dates for one event and they disagreed -- `updated_at` moves when a later bounce refreshes the row. NULL MEANS UNKNOWN: the column was added after this table already had rows, and although the migration backfilled every one of them from `created_at`, the column is nullable and nothing constrains a future writer to fill it. It never means \"not suppressed\" -- the row existing is what suppresses the address, and a null date does not soften that. Sort on it defensively."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-suppressions/import": {
            "post": {
                "operationId": "postEmailSuppressionsImport",
                "summary": "Import (email suppression)",
                "tags": [
                    "Suppressions"
                ],
                "x-required-scope": "suppressions:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "suppression_import"
                                                            ]
                                                        },
                                                        "imported": {
                                                            "type": "integer",
                                                            "description": "Addresses newly suppressed by this call."
                                                        },
                                                        "skipped": {
                                                            "type": "object",
                                                            "description": "Two causes, one category, and a caller deciding whether to re-upload cares about them very differently.",
                                                            "properties": {
                                                                "invalid": {
                                                                    "type": "integer",
                                                                    "description": "Rows that were not addresses. Your file has typos; a 10,000-row list with three of them imports 9,997. An invalid row is never a rejected request."
                                                                },
                                                                "duplicate": {
                                                                    "type": "integer",
                                                                    "description": "Rows already suppressed. Nothing is wrong. Derived from the database's own insert count rather than a pre-check, so it stays exact under a concurrent writer."
                                                                }
                                                            }
                                                        },
                                                        "total": {
                                                            "type": "integer",
                                                            "description": "Rows read. `imported + skipped.invalid + skipped.duplicate` always equals this, exactly -- it is worth relying on."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/email-suppressions/{suppression}": {
            "delete": {
                "operationId": "deleteEmailSuppressionsSuppression",
                "summary": "Remove a suppression",
                "tags": [
                    "Suppressions"
                ],
                "x-required-scope": "suppressions:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "suppression",
                        "in": "path",
                        "required": true,
                        "description": "The suppression identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. Sending to the address is allowed again -- worth doing only when you know the cause is gone, because a removed complaint still happened."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Allows sending to this address again.\n\nWorth doing only when you know why it was suppressed and that the cause is gone \u2014 a\nfixed typo, a mailbox that has been recreated. Removing a spam complaint because you\nwould rather keep sending is how a sending reputation is lost."
            }
        },
        "/api/v1/webhooks": {
            "get": {
                "operationId": "getWebhooks",
                "summary": "List webhooks",
                "tags": [
                    "Webhooks"
                ],
                "x-required-scope": "webhooks:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "webhook"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "description": "Unique identifier for the webhook."
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "description": "Your label for it. Never null: `webhooks.name` is NOT NULL, `POST /webhooks` requires it, and every response that carries a webhook at all -- list, create, update, toggle -- carries it."
                                                            },
                                                            "url": {
                                                                "type": "string",
                                                                "format": "uri",
                                                                "description": "Where events are POSTed. Must be reachable over HTTPS. Never null, for the same reason as `name`: the column is NOT NULL and creation requires it."
                                                            },
                                                            "status": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "active",
                                                                    "inactive"
                                                                ],
                                                                "description": "An `inactive` webhook is skipped by the dispatcher. It is not deleted and keeps its delivery history and its secret."
                                                            },
                                                            "events": {
                                                                "type": "array",
                                                                "items": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "email.accepted",
                                                                        "email.inbound",
                                                                        "email.delivered",
                                                                        "email.bounced",
                                                                        "email.deferred",
                                                                        "email.rejected",
                                                                        "email.dropped",
                                                                        "tracking.open",
                                                                        "tracking.click",
                                                                        "tracking.unsubscribe",
                                                                        "delivery.complaint",
                                                                        "spam.reported",
                                                                        "storage.quota.warning",
                                                                        "storage.quota.exceeded"
                                                                    ]
                                                                },
                                                                "description": "The events this endpoint receives. The enum is the complete set the dispatcher recognises. **`POST /webhooks` does not currently validate these names**: an unrecognised or misspelled value is accepted, stored verbatim, and then never fires, because subscriptions are matched exactly. You get a 200, a signing secret, and silence -- which is indistinguishable from a quiet integration. Check the spelling against this list before you rely on it. `quota.warning` is a legacy alias of `storage.quota.warning`; it still fires, but do not subscribe new webhooks to it."
                                                            },
                                                            "targeting": {
                                                                "type": "object",
                                                                "description": "Narrows which of the subscribed events actually reach this endpoint. Every field is null when it is not narrowing, and **null is not the same as an empty list**: null matches everything, an empty list would match nothing. Null here is always NONE -- there is no such rule on this webhook -- never \"we did not load the rule\": the whole `filters` blob is one column, read with the row.",
                                                                "properties": {
                                                                    "domain": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Exact match, because a domain is an identity and not a search term -- `acme.com` must not also match `notacme.com`. null = any domain."
                                                                    },
                                                                    "sender_includes": {
                                                                        "type": "array",
                                                                        "nullable": true,
                                                                        "items": {
                                                                            "type": "string"
                                                                        },
                                                                        "description": "Any-of substring match on the sender. null = not narrowed."
                                                                    },
                                                                    "subject_contains": {
                                                                        "type": "array",
                                                                        "nullable": true,
                                                                        "items": {
                                                                            "type": "string"
                                                                        },
                                                                        "description": "Any-of substring match on the subject. null = not narrowed."
                                                                    },
                                                                    "body_contains": {
                                                                        "type": "array",
                                                                        "nullable": true,
                                                                        "items": {
                                                                            "type": "string"
                                                                        },
                                                                        "description": "Any-of substring match on the body. null = not narrowed."
                                                                    }
                                                                }
                                                            },
                                                            "deliveries": {
                                                                "type": "object",
                                                                "description": "The delivery history, grouped so the numbers cannot disagree.",
                                                                "properties": {
                                                                    "succeeded": {
                                                                        "type": "integer",
                                                                        "description": "Lifetime tally of accepted deliveries."
                                                                    },
                                                                    "failed": {
                                                                        "type": "integer",
                                                                        "description": "Lifetime tally of failed deliveries."
                                                                    },
                                                                    "consecutive_failures": {
                                                                        "type": "integer",
                                                                        "description": "Resets to zero on any success. This is what drives auto-disable, so it answers a different question from `failed`."
                                                                    },
                                                                    "success_rate": {
                                                                        "type": "number",
                                                                        "format": "float",
                                                                        "nullable": true,
                                                                        "description": "Percentage, 0-100, derived from the two tallies on read rather than stored. **null means no delivery has ever been attempted** -- NONE, not unknown, and emphatically not zero. \"We have sent nothing\" and \"everything we sent failed\" are opposite facts, and the shape this replaced rendered both as `0.00`: a caller alerting on a low success rate paged on every webhook that had simply never fired. Null is the only honest answer to \"what fraction of nothing succeeded\", so a client should show it as \"no deliveries yet\" and not substitute a number for it. `succeeded + failed == 0` is the same condition stated in integers."
                                                                    }
                                                                }
                                                            },
                                                            "last_delivered_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true,
                                                                "description": "ISO 8601 UTC. **null means no delivery to this endpoint has ever been ACCEPTED** -- NONE, since the webhook was created, not \"not recently\" and not \"we did not look\". Read it precisely: the timestamp is written only when an attempt succeeds, so a webhook whose every attempt has failed reports null here while `deliveries.failed` climbs. null therefore does NOT mean \"never tried\" -- check `deliveries` for that. It is never cleared, so disabling and re-enabling a webhook does not reset it."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "description": "ISO 8601 UTC."
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postWebhooks",
                "summary": "Create a webhook endpoint",
                "tags": [
                    "Webhooks"
                ],
                "x-required-scope": "webhooks:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "webhook"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the webhook."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Your label for it. Never null: `webhooks.name` is NOT NULL, `POST /webhooks` requires it, and every response that carries a webhook at all -- list, create, update, toggle -- carries it."
                                                        },
                                                        "url": {
                                                            "type": "string",
                                                            "format": "uri",
                                                            "description": "Where events are POSTed. Must be reachable over HTTPS. Never null, for the same reason as `name`: the column is NOT NULL and creation requires it."
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "inactive"
                                                            ],
                                                            "description": "An `inactive` webhook is skipped by the dispatcher. It is not deleted and keeps its delivery history and its secret."
                                                        },
                                                        "events": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "email.accepted",
                                                                    "email.inbound",
                                                                    "email.delivered",
                                                                    "email.bounced",
                                                                    "email.deferred",
                                                                    "email.rejected",
                                                                    "email.dropped",
                                                                    "tracking.open",
                                                                    "tracking.click",
                                                                    "tracking.unsubscribe",
                                                                    "delivery.complaint",
                                                                    "spam.reported",
                                                                    "storage.quota.warning",
                                                                    "storage.quota.exceeded"
                                                                ]
                                                            },
                                                            "description": "The events this endpoint receives. The enum is the complete set the dispatcher recognises. **`POST /webhooks` does not currently validate these names**: an unrecognised or misspelled value is accepted, stored verbatim, and then never fires, because subscriptions are matched exactly. You get a 200, a signing secret, and silence -- which is indistinguishable from a quiet integration. Check the spelling against this list before you rely on it. `quota.warning` is a legacy alias of `storage.quota.warning`; it still fires, but do not subscribe new webhooks to it."
                                                        },
                                                        "targeting": {
                                                            "type": "object",
                                                            "description": "Narrows which of the subscribed events actually reach this endpoint. Every field is null when it is not narrowing, and **null is not the same as an empty list**: null matches everything, an empty list would match nothing. Null here is always NONE -- there is no such rule on this webhook -- never \"we did not load the rule\": the whole `filters` blob is one column, read with the row.",
                                                            "properties": {
                                                                "domain": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Exact match, because a domain is an identity and not a search term -- `acme.com` must not also match `notacme.com`. null = any domain."
                                                                },
                                                                "sender_includes": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Any-of substring match on the sender. null = not narrowed."
                                                                },
                                                                "subject_contains": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Any-of substring match on the subject. null = not narrowed."
                                                                },
                                                                "body_contains": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Any-of substring match on the body. null = not narrowed."
                                                                }
                                                            }
                                                        },
                                                        "deliveries": {
                                                            "type": "object",
                                                            "description": "The delivery history, grouped so the numbers cannot disagree.",
                                                            "properties": {
                                                                "succeeded": {
                                                                    "type": "integer",
                                                                    "description": "Lifetime tally of accepted deliveries."
                                                                },
                                                                "failed": {
                                                                    "type": "integer",
                                                                    "description": "Lifetime tally of failed deliveries."
                                                                },
                                                                "consecutive_failures": {
                                                                    "type": "integer",
                                                                    "description": "Resets to zero on any success. This is what drives auto-disable, so it answers a different question from `failed`."
                                                                },
                                                                "success_rate": {
                                                                    "type": "number",
                                                                    "format": "float",
                                                                    "nullable": true,
                                                                    "description": "Percentage, 0-100, derived from the two tallies on read rather than stored. **null means no delivery has ever been attempted** -- NONE, not unknown, and emphatically not zero. \"We have sent nothing\" and \"everything we sent failed\" are opposite facts, and the shape this replaced rendered both as `0.00`: a caller alerting on a low success rate paged on every webhook that had simply never fired. Null is the only honest answer to \"what fraction of nothing succeeded\", so a client should show it as \"no deliveries yet\" and not substitute a number for it. `succeeded + failed == 0` is the same condition stated in integers."
                                                                }
                                                            }
                                                        },
                                                        "last_delivered_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means no delivery to this endpoint has ever been ACCEPTED** -- NONE, since the webhook was created, not \"not recently\" and not \"we did not look\". Read it precisely: the timestamp is written only when an attempt succeeds, so a webhook whose every attempt has failed reports null here while `deliveries.failed` climbs. null therefore does NOT mean \"never tried\" -- check `deliveries` for that. It is never cleared, so disabling and re-enabling a webhook does not reset it."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "ISO 8601 UTC."
                                                        },
                                                        "secret": {
                                                            "type": "string",
                                                            "description": "The HMAC signing secret. **Returned once, in the response to `POST /webhooks`. It is never returned on a read, and it cannot be retrieved again** -- not by listing, not by updating, not by support. Store it when you receive it; if you lose it, delete the webhook and create a new one. It is absent rather than null on every other response, because `secret: null` would read as \"this webhook is unsigned\", which is never true. Sign-and-compare it on every request before trusting a payload: a signature is only evidence of origin while the two endpoints are the only parties holding the key."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Registers a URL to receive delivery events as they happen.\n\nDelivery is **at least once**, so the same event can arrive twice \u2014 key your handling\non the event id and make it idempotent. Events can also arrive out of order; a\n`delivered` before the `accepted` that preceded it is normal and not a bug.\n\nVerify the signature on every request before trusting the body. See\n[Receiving webhooks](/developer/guides/receiving-webhooks) for the full list of events\nand their payloads."
            }
        },
        "/api/v1/webhooks/{webhook}": {
            "put": {
                "operationId": "putWebhooksWebhook",
                "summary": "Update a webhook",
                "tags": [
                    "Webhooks"
                ],
                "x-required-scope": "webhooks:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "webhook",
                        "in": "path",
                        "required": true,
                        "description": "The webhook identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "webhook"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the webhook."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Your label for it. Never null: `webhooks.name` is NOT NULL, `POST /webhooks` requires it, and every response that carries a webhook at all -- list, create, update, toggle -- carries it."
                                                        },
                                                        "url": {
                                                            "type": "string",
                                                            "format": "uri",
                                                            "description": "Where events are POSTed. Must be reachable over HTTPS. Never null, for the same reason as `name`: the column is NOT NULL and creation requires it."
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "inactive"
                                                            ],
                                                            "description": "An `inactive` webhook is skipped by the dispatcher. It is not deleted and keeps its delivery history and its secret."
                                                        },
                                                        "events": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "email.accepted",
                                                                    "email.inbound",
                                                                    "email.delivered",
                                                                    "email.bounced",
                                                                    "email.deferred",
                                                                    "email.rejected",
                                                                    "email.dropped",
                                                                    "tracking.open",
                                                                    "tracking.click",
                                                                    "tracking.unsubscribe",
                                                                    "delivery.complaint",
                                                                    "spam.reported",
                                                                    "storage.quota.warning",
                                                                    "storage.quota.exceeded"
                                                                ]
                                                            },
                                                            "description": "The events this endpoint receives. The enum is the complete set the dispatcher recognises. **`POST /webhooks` does not currently validate these names**: an unrecognised or misspelled value is accepted, stored verbatim, and then never fires, because subscriptions are matched exactly. You get a 200, a signing secret, and silence -- which is indistinguishable from a quiet integration. Check the spelling against this list before you rely on it. `quota.warning` is a legacy alias of `storage.quota.warning`; it still fires, but do not subscribe new webhooks to it."
                                                        },
                                                        "targeting": {
                                                            "type": "object",
                                                            "description": "Narrows which of the subscribed events actually reach this endpoint. Every field is null when it is not narrowing, and **null is not the same as an empty list**: null matches everything, an empty list would match nothing. Null here is always NONE -- there is no such rule on this webhook -- never \"we did not load the rule\": the whole `filters` blob is one column, read with the row.",
                                                            "properties": {
                                                                "domain": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Exact match, because a domain is an identity and not a search term -- `acme.com` must not also match `notacme.com`. null = any domain."
                                                                },
                                                                "sender_includes": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Any-of substring match on the sender. null = not narrowed."
                                                                },
                                                                "subject_contains": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Any-of substring match on the subject. null = not narrowed."
                                                                },
                                                                "body_contains": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Any-of substring match on the body. null = not narrowed."
                                                                }
                                                            }
                                                        },
                                                        "deliveries": {
                                                            "type": "object",
                                                            "description": "The delivery history, grouped so the numbers cannot disagree.",
                                                            "properties": {
                                                                "succeeded": {
                                                                    "type": "integer",
                                                                    "description": "Lifetime tally of accepted deliveries."
                                                                },
                                                                "failed": {
                                                                    "type": "integer",
                                                                    "description": "Lifetime tally of failed deliveries."
                                                                },
                                                                "consecutive_failures": {
                                                                    "type": "integer",
                                                                    "description": "Resets to zero on any success. This is what drives auto-disable, so it answers a different question from `failed`."
                                                                },
                                                                "success_rate": {
                                                                    "type": "number",
                                                                    "format": "float",
                                                                    "nullable": true,
                                                                    "description": "Percentage, 0-100, derived from the two tallies on read rather than stored. **null means no delivery has ever been attempted** -- NONE, not unknown, and emphatically not zero. \"We have sent nothing\" and \"everything we sent failed\" are opposite facts, and the shape this replaced rendered both as `0.00`: a caller alerting on a low success rate paged on every webhook that had simply never fired. Null is the only honest answer to \"what fraction of nothing succeeded\", so a client should show it as \"no deliveries yet\" and not substitute a number for it. `succeeded + failed == 0` is the same condition stated in integers."
                                                                }
                                                            }
                                                        },
                                                        "last_delivered_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means no delivery to this endpoint has ever been ACCEPTED** -- NONE, since the webhook was created, not \"not recently\" and not \"we did not look\". Read it precisely: the timestamp is written only when an attempt succeeds, so a webhook whose every attempt has failed reports null here while `deliveries.failed` climbs. null therefore does NOT mean \"never tried\" -- check `deliveries` for that. It is never cleared, so disabling and re-enabling a webhook does not reset it."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "ISO 8601 UTC."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteWebhooksWebhook",
                "summary": "Delete a webhook",
                "tags": [
                    "Webhooks"
                ],
                "x-required-scope": "webhooks:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "webhook",
                        "in": "path",
                        "required": true,
                        "description": "The webhook identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No body. The webhook stops receiving events immediately and its signing secret is discarded with it. This is the recovery path for a lost secret: delete the webhook and create a new one."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/webhooks/{webhook}/toggle": {
            "post": {
                "operationId": "postWebhooksWebhookToggle",
                "summary": "Toggle a webhook",
                "tags": [
                    "Webhooks"
                ],
                "x-required-scope": "webhooks:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "webhook",
                        "in": "path",
                        "required": true,
                        "description": "The webhook identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "webhook"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the webhook."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "Your label for it. Never null: `webhooks.name` is NOT NULL, `POST /webhooks` requires it, and every response that carries a webhook at all -- list, create, update, toggle -- carries it."
                                                        },
                                                        "url": {
                                                            "type": "string",
                                                            "format": "uri",
                                                            "description": "Where events are POSTed. Must be reachable over HTTPS. Never null, for the same reason as `name`: the column is NOT NULL and creation requires it."
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "enum": [
                                                                "active",
                                                                "inactive"
                                                            ],
                                                            "description": "An `inactive` webhook is skipped by the dispatcher. It is not deleted and keeps its delivery history and its secret."
                                                        },
                                                        "events": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "email.accepted",
                                                                    "email.inbound",
                                                                    "email.delivered",
                                                                    "email.bounced",
                                                                    "email.deferred",
                                                                    "email.rejected",
                                                                    "email.dropped",
                                                                    "tracking.open",
                                                                    "tracking.click",
                                                                    "tracking.unsubscribe",
                                                                    "delivery.complaint",
                                                                    "spam.reported",
                                                                    "storage.quota.warning",
                                                                    "storage.quota.exceeded"
                                                                ]
                                                            },
                                                            "description": "The events this endpoint receives. The enum is the complete set the dispatcher recognises. **`POST /webhooks` does not currently validate these names**: an unrecognised or misspelled value is accepted, stored verbatim, and then never fires, because subscriptions are matched exactly. You get a 200, a signing secret, and silence -- which is indistinguishable from a quiet integration. Check the spelling against this list before you rely on it. `quota.warning` is a legacy alias of `storage.quota.warning`; it still fires, but do not subscribe new webhooks to it."
                                                        },
                                                        "targeting": {
                                                            "type": "object",
                                                            "description": "Narrows which of the subscribed events actually reach this endpoint. Every field is null when it is not narrowing, and **null is not the same as an empty list**: null matches everything, an empty list would match nothing. Null here is always NONE -- there is no such rule on this webhook -- never \"we did not load the rule\": the whole `filters` blob is one column, read with the row.",
                                                            "properties": {
                                                                "domain": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Exact match, because a domain is an identity and not a search term -- `acme.com` must not also match `notacme.com`. null = any domain."
                                                                },
                                                                "sender_includes": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Any-of substring match on the sender. null = not narrowed."
                                                                },
                                                                "subject_contains": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Any-of substring match on the subject. null = not narrowed."
                                                                },
                                                                "body_contains": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Any-of substring match on the body. null = not narrowed."
                                                                }
                                                            }
                                                        },
                                                        "deliveries": {
                                                            "type": "object",
                                                            "description": "The delivery history, grouped so the numbers cannot disagree.",
                                                            "properties": {
                                                                "succeeded": {
                                                                    "type": "integer",
                                                                    "description": "Lifetime tally of accepted deliveries."
                                                                },
                                                                "failed": {
                                                                    "type": "integer",
                                                                    "description": "Lifetime tally of failed deliveries."
                                                                },
                                                                "consecutive_failures": {
                                                                    "type": "integer",
                                                                    "description": "Resets to zero on any success. This is what drives auto-disable, so it answers a different question from `failed`."
                                                                },
                                                                "success_rate": {
                                                                    "type": "number",
                                                                    "format": "float",
                                                                    "nullable": true,
                                                                    "description": "Percentage, 0-100, derived from the two tallies on read rather than stored. **null means no delivery has ever been attempted** -- NONE, not unknown, and emphatically not zero. \"We have sent nothing\" and \"everything we sent failed\" are opposite facts, and the shape this replaced rendered both as `0.00`: a caller alerting on a low success rate paged on every webhook that had simply never fired. Null is the only honest answer to \"what fraction of nothing succeeded\", so a client should show it as \"no deliveries yet\" and not substitute a number for it. `succeeded + failed == 0` is the same condition stated in integers."
                                                                }
                                                            }
                                                        },
                                                        "last_delivered_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. **null means no delivery to this endpoint has ever been ACCEPTED** -- NONE, since the webhook was created, not \"not recently\" and not \"we did not look\". Read it precisely: the timestamp is written only when an attempt succeeds, so a webhook whose every attempt has failed reports null here while `deliveries.failed` climbs. null therefore does NOT mean \"never tried\" -- check `deliveries` for that. It is never cleared, so disabling and re-enabling a webhook does not reset it."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "ISO 8601 UTC."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contacts": {
            "get": {
                "operationId": "getContacts",
                "summary": "List contacts",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "since_last_changed",
                        "in": "query",
                        "required": false,
                        "description": "ISO 8601. Returns only contacts modified strictly after this moment. URL-encode it.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "state",
                        "in": "query",
                        "required": false,
                        "description": "One of `subscribed`, `unsubscribed`, `bounced`, `complained`, `suppressed`. What the product will do, suppression list included.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "The stored row value. Kept because it is published; prefer `state`.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Matches email or name.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "list_id",
                        "in": "query",
                        "required": false,
                        "description": "Only contacts on this list.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "tag",
                        "in": "query",
                        "required": false,
                        "description": "Only contacts carrying this tag, matched by NAME and case-insensitively \u2014 tags are written by name everywhere, never by id.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "interest_id",
                        "in": "query",
                        "required": false,
                        "description": "Only contacts who chose this interest, matched by ID. An interest's name is form copy; rewording it must not change who matches.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "required": false,
                        "description": "Page size.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "contact"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Unique identifier for the contact."
                                                                    },
                                                                    "email": {
                                                                        "type": "string",
                                                                        "format": "email",
                                                                        "description": "Lower-cased and trimmed on write, so the address you read back may not be byte-identical to the one you sent."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The contact's display name. `null` means NONE \u2014 an address is all a contact needs, the column is nullable and neither create nor import requires one. It is not \"we did not look\": the name is on the row we already read. `{{ name }}` renders as the empty string for these contacts unless the template supplies its own inline fallback \u2014 a contact-field default cannot fill it, because `name` is a reserved key applied after the defaults are merged."
                                                                    },
                                                                    "state": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "subscribed",
                                                                            "unsubscribed",
                                                                            "bounced",
                                                                            "complained",
                                                                            "suppressed"
                                                                        ],
                                                                        "description": "The answer to \"will this contact be mailed\". `subscribed` is exactly \"we will attempt delivery\"; every other value is the reason we will not. DERIVED, and read-only \u2014 it reconciles the writable `status` field with the organization-wide suppression list, which are two independent gates that can and do disagree: `status` is read when a campaign's recipient set is built, the suppression list is read at send time per message, and nothing keeps them in step. A contact whose `status` says `subscribed` but whose address \u2014 or whose whole domain \u2014 is suppressed reads `suppressed` here, and no message will leave. The contact's own recorded decision outranks the list, so somebody who unsubscribed reads `unsubscribed` even when both are true of them. A stored status we do not recognise reads `unsubscribed`, never `subscribed`: guessing \"mailable\" from a value we cannot read is how people get mailed who asked not to be. **`status` is the separate, writable field**, and it accepts only `subscribed`, `unsubscribed`, `bounced` and `complained` \u2014 `suppressed` is not something you can set on a contact, it is something the suppression list does to them, which is why the two have different names. Note that `GET /contacts?status=` filters the stored column, not this field."
                                                                    },
                                                                    "fields": {
                                                                        "type": "object",
                                                                        "additionalProperties": {
                                                                            "type": "string"
                                                                        },
                                                                        "description": "Custom field values, keyed by the field `key` that `GET /contact-fields` publishes and that `{{ signup_date }}` resolves \u2014 NEVER by a `contact_field` id, which identifies the definition and appears only as that resource's `id`. **Always an object**: `{}` when the contact has no values, never a list. Free-form \u2014 a key written through the API or an import with no `contact_field` definition behind it is still a real value on the contact and is included here; `GET /contacts/attribute-keys` is where you learn which keys are declared. Values are strings as stored: a field's `type` is an editing hint, not a storage type, and nothing is coerced. Field `default_value`s are NOT merged in \u2014 they are applied at send time, and merging them here would turn a default into a real value on your next write. The matching INPUT key is still spelled `attributes`."
                                                                    },
                                                                    "lists": {
                                                                        "type": "array",
                                                                        "nullable": true,
                                                                        "items": {
                                                                            "type": "object",
                                                                            "properties": {
                                                                                "id": {
                                                                                    "type": "string"
                                                                                },
                                                                                "name": {
                                                                                    "type": "string"
                                                                                }
                                                                            }
                                                                        },
                                                                        "description": "The contact lists this contact belongs to, NAMED, so you do not have to fetch each one to display it \u2014 every path that returns a contact already loads them. They carry no `contact_count`: that is a property of the LIST, not of this membership, and `contact_list.contact_count` is where it is published. `null` means UNKNOWN \u2014 the membership pivot was not loaded for this response \u2014 and never `[]`, which would claim the contact belongs to no list. **The matching INPUT key is still spelled `list_ids`** and still takes bare ids, on create and on update."
                                                                    },
                                                                    "tags": {
                                                                        "type": "array",
                                                                        "nullable": true,
                                                                        "items": {
                                                                            "type": "object",
                                                                            "properties": {
                                                                                "id": {
                                                                                    "type": "string"
                                                                                },
                                                                                "name": {
                                                                                    "type": "string"
                                                                                }
                                                                            }
                                                                        },
                                                                        "description": "Your own labels on this contact, NAMED. A tag is something you put on a contact and it stays there; a SEGMENT is a rule re-evaluated every time it is read, so its membership changes without anybody editing a contact. They are separate resources here for that reason. No `contact_count`: that belongs to the tag rather than to this contact having it, and `GET /contact-tags` publishes it. `null` means UNKNOWN \u2014 the relation was not loaded \u2014 never that this contact is untagged."
                                                                    },
                                                                    "interests": {
                                                                        "type": "array",
                                                                        "nullable": true,
                                                                        "description": "What this contact CHOSE \u2014 the answers they ticked on a form, as opposed to `tags`, which are labels you put on them and they never see. Each carries the question it answers, because an answer name is meaningless without it and two groups may share one. `null` MEANS NOT INCLUDED \u2014 the relation was not loaded on this response. An empty array means the contact chose nothing, which is a different fact.",
                                                                        "items": {
                                                                            "type": "object",
                                                                            "properties": {
                                                                                "id": {
                                                                                    "type": "string",
                                                                                    "description": "Match on this in a segment rule, never on the name."
                                                                                },
                                                                                "name": {
                                                                                    "type": "string",
                                                                                    "description": "The answer, as the contact read it."
                                                                                },
                                                                                "category_id": {
                                                                                    "type": "string",
                                                                                    "description": "The question this answers."
                                                                                },
                                                                                "category_title": {
                                                                                    "type": "string",
                                                                                    "nullable": true,
                                                                                    "description": "The question in words. `null` MEANS NOT INCLUDED \u2014 the category was not loaded, never that the question has no title."
                                                                                }
                                                                            }
                                                                        }
                                                                    },
                                                                    "consent": {
                                                                        "type": "object",
                                                                        "description": "Evidence of how this contact opted in. Every field is NULL MEANS UNKNOWN \u2014 we do not hold the record \u2014 and never \"no consent was given\", which is the opposite claim and not one we can make on your behalf. Set it when you import from another provider so your lawful basis moves with your contacts.",
                                                                        "properties": {
                                                                            "at": {
                                                                                "type": "string",
                                                                                "format": "date-time",
                                                                                "nullable": true,
                                                                                "description": "When they opted in, as recorded by whoever collected it. NULL MEANS UNKNOWN."
                                                                            },
                                                                            "ip": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The address the opt-in came from. NULL MEANS UNKNOWN."
                                                                            },
                                                                            "source": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "Where: a form name, a URL, \"imported from Mailchimp\". Free text rather than an enum, because the shapes this takes across providers are not enumerable and an enum would force the evidence to be discarded to fit. NULL MEANS UNKNOWN."
                                                                            }
                                                                        }
                                                                    },
                                                                    "source": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "How this contact arrived. Free-form, not an enum: any string up to 50 characters is accepted on create. The values we set ourselves are `manual`, `import_api` and `import_csv`. `null` means NONE \u2014 nothing was recorded \u2014 not \"we did not look\" and not \"we do not know where they came from\": a contact created through this API is stamped `manual` when you send no `source`, and an import stamps its own, so a null here is a row that predates the column or one a caller explicitly cleared."
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    },
                                                                    "updated_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Your contacts, newest first.\n\n**For a sync, use `since_last_changed`.** It answers the only question an integration\nkeeping its own copy actually has \u2014 what moved \u2014 and turns a nightly full-list crawl into a\nrequest that usually returns nothing. The value is an ISO 8601 timestamp; remember to\nURL-encode it, because the `+` in `+00:00` means a space in a query string.\n\nA `since_last_changed` we cannot parse is IGNORED and you get everything, rather than\nnothing. The two failures are not symmetrical: a sync handed zero rows concludes it is up to\ndate and stops, and silently misses every change from then on.\n\n**Filter on `state`, not `status`.** `status` is what the contact row says; `state` is what\nthe product will actually do, and reconciles that row against your organization's\nsuppression list. A contact whose row says `subscribed` but whose address you suppressed\nanswers `state: \"suppressed\"` and will never be mailed \u2014 `?status=subscribed` used to hand\nthose back under a filter that claims to select the ones it will send to."
            },
            "post": {
                "operationId": "postContacts",
                "summary": "Create a contact",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the contact."
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "Lower-cased and trimmed on write, so the address you read back may not be byte-identical to the one you sent."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The contact's display name. `null` means NONE \u2014 an address is all a contact needs, the column is nullable and neither create nor import requires one. It is not \"we did not look\": the name is on the row we already read. `{{ name }}` renders as the empty string for these contacts unless the template supplies its own inline fallback \u2014 a contact-field default cannot fill it, because `name` is a reserved key applied after the defaults are merged."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "subscribed",
                                                                "unsubscribed",
                                                                "bounced",
                                                                "complained",
                                                                "suppressed"
                                                            ],
                                                            "description": "The answer to \"will this contact be mailed\". `subscribed` is exactly \"we will attempt delivery\"; every other value is the reason we will not. DERIVED, and read-only \u2014 it reconciles the writable `status` field with the organization-wide suppression list, which are two independent gates that can and do disagree: `status` is read when a campaign's recipient set is built, the suppression list is read at send time per message, and nothing keeps them in step. A contact whose `status` says `subscribed` but whose address \u2014 or whose whole domain \u2014 is suppressed reads `suppressed` here, and no message will leave. The contact's own recorded decision outranks the list, so somebody who unsubscribed reads `unsubscribed` even when both are true of them. A stored status we do not recognise reads `unsubscribed`, never `subscribed`: guessing \"mailable\" from a value we cannot read is how people get mailed who asked not to be. **`status` is the separate, writable field**, and it accepts only `subscribed`, `unsubscribed`, `bounced` and `complained` \u2014 `suppressed` is not something you can set on a contact, it is something the suppression list does to them, which is why the two have different names. Note that `GET /contacts?status=` filters the stored column, not this field."
                                                        },
                                                        "fields": {
                                                            "type": "object",
                                                            "additionalProperties": {
                                                                "type": "string"
                                                            },
                                                            "description": "Custom field values, keyed by the field `key` that `GET /contact-fields` publishes and that `{{ signup_date }}` resolves \u2014 NEVER by a `contact_field` id, which identifies the definition and appears only as that resource's `id`. **Always an object**: `{}` when the contact has no values, never a list. Free-form \u2014 a key written through the API or an import with no `contact_field` definition behind it is still a real value on the contact and is included here; `GET /contacts/attribute-keys` is where you learn which keys are declared. Values are strings as stored: a field's `type` is an editing hint, not a storage type, and nothing is coerced. Field `default_value`s are NOT merged in \u2014 they are applied at send time, and merging them here would turn a default into a real value on your next write. The matching INPUT key is still spelled `attributes`."
                                                        },
                                                        "lists": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "The contact lists this contact belongs to, NAMED, so you do not have to fetch each one to display it \u2014 every path that returns a contact already loads them. They carry no `contact_count`: that is a property of the LIST, not of this membership, and `contact_list.contact_count` is where it is published. `null` means UNKNOWN \u2014 the membership pivot was not loaded for this response \u2014 and never `[]`, which would claim the contact belongs to no list. **The matching INPUT key is still spelled `list_ids`** and still takes bare ids, on create and on update."
                                                        },
                                                        "tags": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "Your own labels on this contact, NAMED. A tag is something you put on a contact and it stays there; a SEGMENT is a rule re-evaluated every time it is read, so its membership changes without anybody editing a contact. They are separate resources here for that reason. No `contact_count`: that belongs to the tag rather than to this contact having it, and `GET /contact-tags` publishes it. `null` means UNKNOWN \u2014 the relation was not loaded \u2014 never that this contact is untagged."
                                                        },
                                                        "interests": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "description": "What this contact CHOSE \u2014 the answers they ticked on a form, as opposed to `tags`, which are labels you put on them and they never see. Each carries the question it answers, because an answer name is meaningless without it and two groups may share one. `null` MEANS NOT INCLUDED \u2014 the relation was not loaded on this response. An empty array means the contact chose nothing, which is a different fact.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Match on this in a segment rule, never on the name."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "description": "The answer, as the contact read it."
                                                                    },
                                                                    "category_id": {
                                                                        "type": "string",
                                                                        "description": "The question this answers."
                                                                    },
                                                                    "category_title": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The question in words. `null` MEANS NOT INCLUDED \u2014 the category was not loaded, never that the question has no title."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "consent": {
                                                            "type": "object",
                                                            "description": "Evidence of how this contact opted in. Every field is NULL MEANS UNKNOWN \u2014 we do not hold the record \u2014 and never \"no consent was given\", which is the opposite claim and not one we can make on your behalf. Set it when you import from another provider so your lawful basis moves with your contacts.",
                                                            "properties": {
                                                                "at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When they opted in, as recorded by whoever collected it. NULL MEANS UNKNOWN."
                                                                },
                                                                "ip": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The address the opt-in came from. NULL MEANS UNKNOWN."
                                                                },
                                                                "source": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Where: a form name, a URL, \"imported from Mailchimp\". Free text rather than an enum, because the shapes this takes across providers are not enumerable and an enum would force the evidence to be discarded to fit. NULL MEANS UNKNOWN."
                                                                }
                                                            }
                                                        },
                                                        "source": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "How this contact arrived. Free-form, not an enum: any string up to 50 characters is accepted on create. The values we set ourselves are `manual`, `import_api` and `import_csv`. `null` means NONE \u2014 nothing was recorded \u2014 not \"we did not look\" and not \"we do not know where they came from\": a contact created through this API is stamped `manual` when you send no `source`, and an import stamps its own, so a null here is a row that predates the column or one a caller explicitly cleared."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "operationId": "putContacts",
                "summary": "Create or update a contact",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "201 when the contact was created, 200 when it already existed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the contact."
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "Lower-cased and trimmed on write, so the address you read back may not be byte-identical to the one you sent."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The contact's display name. `null` means NONE \u2014 an address is all a contact needs, the column is nullable and neither create nor import requires one. It is not \"we did not look\": the name is on the row we already read. `{{ name }}` renders as the empty string for these contacts unless the template supplies its own inline fallback \u2014 a contact-field default cannot fill it, because `name` is a reserved key applied after the defaults are merged."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "subscribed",
                                                                "unsubscribed",
                                                                "bounced",
                                                                "complained",
                                                                "suppressed"
                                                            ],
                                                            "description": "The answer to \"will this contact be mailed\". `subscribed` is exactly \"we will attempt delivery\"; every other value is the reason we will not. DERIVED, and read-only \u2014 it reconciles the writable `status` field with the organization-wide suppression list, which are two independent gates that can and do disagree: `status` is read when a campaign's recipient set is built, the suppression list is read at send time per message, and nothing keeps them in step. A contact whose `status` says `subscribed` but whose address \u2014 or whose whole domain \u2014 is suppressed reads `suppressed` here, and no message will leave. The contact's own recorded decision outranks the list, so somebody who unsubscribed reads `unsubscribed` even when both are true of them. A stored status we do not recognise reads `unsubscribed`, never `subscribed`: guessing \"mailable\" from a value we cannot read is how people get mailed who asked not to be. **`status` is the separate, writable field**, and it accepts only `subscribed`, `unsubscribed`, `bounced` and `complained` \u2014 `suppressed` is not something you can set on a contact, it is something the suppression list does to them, which is why the two have different names. Note that `GET /contacts?status=` filters the stored column, not this field."
                                                        },
                                                        "fields": {
                                                            "type": "object",
                                                            "additionalProperties": {
                                                                "type": "string"
                                                            },
                                                            "description": "Custom field values, keyed by the field `key` that `GET /contact-fields` publishes and that `{{ signup_date }}` resolves \u2014 NEVER by a `contact_field` id, which identifies the definition and appears only as that resource's `id`. **Always an object**: `{}` when the contact has no values, never a list. Free-form \u2014 a key written through the API or an import with no `contact_field` definition behind it is still a real value on the contact and is included here; `GET /contacts/attribute-keys` is where you learn which keys are declared. Values are strings as stored: a field's `type` is an editing hint, not a storage type, and nothing is coerced. Field `default_value`s are NOT merged in \u2014 they are applied at send time, and merging them here would turn a default into a real value on your next write. The matching INPUT key is still spelled `attributes`."
                                                        },
                                                        "lists": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "The contact lists this contact belongs to, NAMED, so you do not have to fetch each one to display it \u2014 every path that returns a contact already loads them. They carry no `contact_count`: that is a property of the LIST, not of this membership, and `contact_list.contact_count` is where it is published. `null` means UNKNOWN \u2014 the membership pivot was not loaded for this response \u2014 and never `[]`, which would claim the contact belongs to no list. **The matching INPUT key is still spelled `list_ids`** and still takes bare ids, on create and on update."
                                                        },
                                                        "tags": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "Your own labels on this contact, NAMED. A tag is something you put on a contact and it stays there; a SEGMENT is a rule re-evaluated every time it is read, so its membership changes without anybody editing a contact. They are separate resources here for that reason. No `contact_count`: that belongs to the tag rather than to this contact having it, and `GET /contact-tags` publishes it. `null` means UNKNOWN \u2014 the relation was not loaded \u2014 never that this contact is untagged."
                                                        },
                                                        "interests": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "description": "What this contact CHOSE \u2014 the answers they ticked on a form, as opposed to `tags`, which are labels you put on them and they never see. Each carries the question it answers, because an answer name is meaningless without it and two groups may share one. `null` MEANS NOT INCLUDED \u2014 the relation was not loaded on this response. An empty array means the contact chose nothing, which is a different fact.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Match on this in a segment rule, never on the name."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "description": "The answer, as the contact read it."
                                                                    },
                                                                    "category_id": {
                                                                        "type": "string",
                                                                        "description": "The question this answers."
                                                                    },
                                                                    "category_title": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The question in words. `null` MEANS NOT INCLUDED \u2014 the category was not loaded, never that the question has no title."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "consent": {
                                                            "type": "object",
                                                            "description": "Evidence of how this contact opted in. Every field is NULL MEANS UNKNOWN \u2014 we do not hold the record \u2014 and never \"no consent was given\", which is the opposite claim and not one we can make on your behalf. Set it when you import from another provider so your lawful basis moves with your contacts.",
                                                            "properties": {
                                                                "at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When they opted in, as recorded by whoever collected it. NULL MEANS UNKNOWN."
                                                                },
                                                                "ip": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The address the opt-in came from. NULL MEANS UNKNOWN."
                                                                },
                                                                "source": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Where: a form name, a URL, \"imported from Mailchimp\". Free text rather than an enum, because the shapes this takes across providers are not enumerable and an enum would force the evidence to be discarded to fit. NULL MEANS UNKNOWN."
                                                                }
                                                            }
                                                        },
                                                        "source": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "How this contact arrived. Free-form, not an enum: any string up to 50 characters is accepted on create. The values we set ourselves are `manual`, `import_api` and `import_csv`. `null` means NONE \u2014 nothing was recorded \u2014 not \"we did not look\" and not \"we do not know where they came from\": a contact created through this API is stamped `manual` when you send no `source`, and an import stamps its own, so a null here is a row that predates the column or one a caller explicitly cleared."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Creates the contact if this email is new, updates it if it is not \u2014 the call to reach for\nwhen you are keeping your own database in step with ours.\n\nWithout it a sync needs a GET, a branch, and then a POST or a PATCH: three round trips, and\na race between the read and the write.\n\n**`status_if_new` is the one to understand.** It applies only when the contact is created.\nA nightly sync that sends `status: subscribed` for everybody in your CRM would resurrect\nevery unsubscribe it touched \u2014 the worst thing this API can do to you, because the person\nasked not to be mailed and then was. Send `status_if_new` to say \"subscribed as far as I\nknow\" without overriding what the contact themselves decided here; send `status` only when\nyou mean to change it.\n\nLists named in `list_ids` are added. The contact's other memberships are left alone.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "email"
                                ],
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "description": "The key. Matched case-insensitively."
                                    },
                                    "name": {
                                        "type": "string"
                                    },
                                    "attributes": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Custom field values."
                                    },
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "subscribed",
                                            "unsubscribed",
                                            "bounced",
                                            "complained"
                                        ],
                                        "description": "Applied whether the contact is new or existing. Use it only when you mean to change somebody\u2019s state."
                                    },
                                    "status_if_new": {
                                        "type": "string",
                                        "enum": [
                                            "subscribed",
                                            "unsubscribed",
                                            "bounced",
                                            "complained"
                                        ],
                                        "description": "Applied ONLY on create, and ignored for a contact that already exists. This is what makes a repeated sync safe."
                                    },
                                    "source": {
                                        "type": "string"
                                    },
                                    "list_ids": {
                                        "type": "array",
                                        "items": {
                                            "type": "string"
                                        }
                                    },
                                    "consented_at": {
                                        "type": "string",
                                        "format": "date-time",
                                        "description": "When this person agreed to be mailed. Bring it with you when you migrate: under GDPR the lawful basis for mailing somebody is a RECORD, not a belief, and a record left behind in your old tool is a record you no longer have."
                                    },
                                    "consent_ip": {
                                        "type": "string",
                                        "description": "The address the agreement came from. IPv4 or IPv6."
                                    },
                                    "consent_source": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "Where it happened, in your own words \u2014 a form name, a checkout step, \"imported from Mailchimp\". Free text, because what counts as evidence differs by regulator and we will not pick for you."
                                    }
                                }
                            },
                            "example": {
                                "email": "ada@example.com",
                                "name": "Ada Lovelace",
                                "status_if_new": "subscribed",
                                "attributes": {
                                    "plan": "pro"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/contacts/import": {
            "post": {
                "operationId": "postContactsImport",
                "summary": "Import contacts",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The counters always sum: `imported + skipped_invalid + skipped_duplicate == total`.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_import"
                                                            ]
                                                        },
                                                        "total": {
                                                            "type": "integer",
                                                            "description": "Rows we were given. For a CSV this is DATA rows \u2014 a recognised header row is not counted."
                                                        },
                                                        "imported": {
                                                            "type": "integer",
                                                            "description": "Rows that became new contacts."
                                                        },
                                                        "skipped_invalid": {
                                                            "type": "integer",
                                                            "description": "Rows with a missing or unparseable email address, or with no value for a field this organization marked required. An invalid row is skipped and counted, never fatal: a 10,000-row file with one bad address still imports 9,999."
                                                        },
                                                        "skipped_duplicate": {
                                                            "type": "integer",
                                                            "description": "Addresses already known to this organization, plus repeats within the batch itself. Import is insert-or-SKIP, not an upsert \u2014 an address already on file keeps its name, its custom fields and, most importantly, its state, so re-importing a list can never resurrect somebody who unsubscribed."
                                                        },
                                                        "error_count": {
                                                            "type": "integer",
                                                            "description": "How many rows failed in total. Equal to `skipped_invalid + skipped_duplicate`, and the number to trust \u2014 `errors` below is capped, so a file where everything failed reports 4,000 here and lists 100."
                                                        },
                                                        "errors": {
                                                            "type": "array",
                                                            "description": "The failed rows, in FILE ORDER, so you can read this beside your spreadsheet. Capped at 100: the first hundred show the pattern \u2014 a mis-mapped column, a stray header \u2014 and `error_count` says how many there really were. An empty array means every row was accepted.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "row": {
                                                                        "type": "integer",
                                                                        "description": "1-based, counting DATA rows, so it lines up with your spreadsheet after the header."
                                                                    },
                                                                    "email": {
                                                                        "type": "string",
                                                                        "description": "The address exactly as you sent it, before normalising \u2014 empty when the row had none."
                                                                    },
                                                                    "reason": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "missing_email",
                                                                            "invalid_email",
                                                                            "duplicate_in_file",
                                                                            "already_exists",
                                                                            "missing_required_field"
                                                                        ],
                                                                        "description": "Machine-readable. `duplicate_in_file` and `already_exists` both count toward `skipped_duplicate` but are different problems with different fixes: one is a typo in your file, the other is a contact you already have. `missing_required_field` means your organization marked a contact field required and this row has no value for it \u2014 the fix is a column, not an address, and `message` names which one."
                                                                    },
                                                                    "message": {
                                                                        "type": "string",
                                                                        "description": "The same thing in words, safe to show a person. For a duplicate it names the earlier row."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Bulk-create or update contacts. Existing contacts are matched on email address and updated rather than duplicated."
            }
        },
        "/api/v1/contacts/attribute-keys": {
            "get": {
                "operationId": "getContactsAttributeKeys",
                "summary": "Attribute Keys (contact)",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "description": "One usable key of a contact's `fields` object. Serves both `GET /contact-fields` (the declared catalog) and `GET /contacts/attribute-keys` (the catalog plus keys observed on contact data), which is why `declared` exists.",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "contact_field"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "The definition's id, for `PUT`/`DELETE /contact-fields/{field}`. `null` when `declared` is false \u2014 there is no definition row, so there is nothing to address."
                                                            },
                                                            "key": {
                                                                "type": "string",
                                                                "description": "The stable name. This is the key inside a contact's `fields` object and the `{{ signup_date }}` tag in campaign content. Contact values are keyed by this, never by `id`."
                                                            },
                                                            "declared": {
                                                                "type": "boolean",
                                                                "description": "Whether this organization has DEFINED the key, or we merely observed it on contact data. Both are usable in content and in segment rules; only a declared one has a stored label, type and default. Every write path registers a definition for a key it has not seen before \u2014 `POST`, `PATCH` and `PUT /contacts` as well as `POST /contacts/import` \u2014 so which endpoint wrote a key no longer decides which side of this line it lands on. An undeclared key is one that arrived before that was true, or one whose name is not a legal key."
                                                            },
                                                            "label": {
                                                                "type": "string",
                                                                "description": "Display name. Derived from the key for an undeclared one."
                                                            },
                                                            "type": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "text",
                                                                    "number",
                                                                    "date",
                                                                    "boolean"
                                                                ],
                                                                "description": "How a value should be EDITED and displayed. Not a storage type: every value in a contact's `fields` object is a string whatever this says, and nothing is coerced."
                                                            },
                                                            "required": {
                                                                "type": "boolean",
                                                                "description": "Whether every contact must carry a value. Enforced in two places and only two: a contact being CREATED must supply it, and an update may not CLEAR a value that was already there. It is never checked retroactively, so marking a field required does not start failing your sync on contacts that predate the decision \u2014 which is the only way anyone could safely turn it on for a live audience. `default_value` does not satisfy it: the default is a render-time placeholder, and accepting a placeholder for a field you marked required is the opposite of what you asked for. Always false for an undeclared key."
                                                            },
                                                            "default_value": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "Substituted at send time for contacts with no value of their own. It is never written into a contact's `fields`."
                                                            },
                                                            "help_text": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "The hint shown beside this field on a form. `null` MEANS NONE WAS WRITTEN \u2014 it carries no behaviour, so an absent hint changes nothing about what the field accepts."
                                                            },
                                                            "contacts_with_value": {
                                                                "type": "integer",
                                                                "description": "How many contacts carry a non-empty value for this key \u2014 the \"is it safe to delete this\" signal. Always an integer."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true,
                                                                "description": "`null` when `declared` is false: an observed key has no definition row and therefore no creation time. Genuinely unknown, not zero."
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contacts/{contact}": {
            "get": {
                "operationId": "getContactsContact",
                "summary": "Retrieve a contact",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "description": "The contact identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the contact."
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "Lower-cased and trimmed on write, so the address you read back may not be byte-identical to the one you sent."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The contact's display name. `null` means NONE \u2014 an address is all a contact needs, the column is nullable and neither create nor import requires one. It is not \"we did not look\": the name is on the row we already read. `{{ name }}` renders as the empty string for these contacts unless the template supplies its own inline fallback \u2014 a contact-field default cannot fill it, because `name` is a reserved key applied after the defaults are merged."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "subscribed",
                                                                "unsubscribed",
                                                                "bounced",
                                                                "complained",
                                                                "suppressed"
                                                            ],
                                                            "description": "The answer to \"will this contact be mailed\". `subscribed` is exactly \"we will attempt delivery\"; every other value is the reason we will not. DERIVED, and read-only \u2014 it reconciles the writable `status` field with the organization-wide suppression list, which are two independent gates that can and do disagree: `status` is read when a campaign's recipient set is built, the suppression list is read at send time per message, and nothing keeps them in step. A contact whose `status` says `subscribed` but whose address \u2014 or whose whole domain \u2014 is suppressed reads `suppressed` here, and no message will leave. The contact's own recorded decision outranks the list, so somebody who unsubscribed reads `unsubscribed` even when both are true of them. A stored status we do not recognise reads `unsubscribed`, never `subscribed`: guessing \"mailable\" from a value we cannot read is how people get mailed who asked not to be. **`status` is the separate, writable field**, and it accepts only `subscribed`, `unsubscribed`, `bounced` and `complained` \u2014 `suppressed` is not something you can set on a contact, it is something the suppression list does to them, which is why the two have different names. Note that `GET /contacts?status=` filters the stored column, not this field."
                                                        },
                                                        "fields": {
                                                            "type": "object",
                                                            "additionalProperties": {
                                                                "type": "string"
                                                            },
                                                            "description": "Custom field values, keyed by the field `key` that `GET /contact-fields` publishes and that `{{ signup_date }}` resolves \u2014 NEVER by a `contact_field` id, which identifies the definition and appears only as that resource's `id`. **Always an object**: `{}` when the contact has no values, never a list. Free-form \u2014 a key written through the API or an import with no `contact_field` definition behind it is still a real value on the contact and is included here; `GET /contacts/attribute-keys` is where you learn which keys are declared. Values are strings as stored: a field's `type` is an editing hint, not a storage type, and nothing is coerced. Field `default_value`s are NOT merged in \u2014 they are applied at send time, and merging them here would turn a default into a real value on your next write. The matching INPUT key is still spelled `attributes`."
                                                        },
                                                        "lists": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "The contact lists this contact belongs to, NAMED, so you do not have to fetch each one to display it \u2014 every path that returns a contact already loads them. They carry no `contact_count`: that is a property of the LIST, not of this membership, and `contact_list.contact_count` is where it is published. `null` means UNKNOWN \u2014 the membership pivot was not loaded for this response \u2014 and never `[]`, which would claim the contact belongs to no list. **The matching INPUT key is still spelled `list_ids`** and still takes bare ids, on create and on update."
                                                        },
                                                        "tags": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "Your own labels on this contact, NAMED. A tag is something you put on a contact and it stays there; a SEGMENT is a rule re-evaluated every time it is read, so its membership changes without anybody editing a contact. They are separate resources here for that reason. No `contact_count`: that belongs to the tag rather than to this contact having it, and `GET /contact-tags` publishes it. `null` means UNKNOWN \u2014 the relation was not loaded \u2014 never that this contact is untagged."
                                                        },
                                                        "interests": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "description": "What this contact CHOSE \u2014 the answers they ticked on a form, as opposed to `tags`, which are labels you put on them and they never see. Each carries the question it answers, because an answer name is meaningless without it and two groups may share one. `null` MEANS NOT INCLUDED \u2014 the relation was not loaded on this response. An empty array means the contact chose nothing, which is a different fact.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Match on this in a segment rule, never on the name."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "description": "The answer, as the contact read it."
                                                                    },
                                                                    "category_id": {
                                                                        "type": "string",
                                                                        "description": "The question this answers."
                                                                    },
                                                                    "category_title": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The question in words. `null` MEANS NOT INCLUDED \u2014 the category was not loaded, never that the question has no title."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "consent": {
                                                            "type": "object",
                                                            "description": "Evidence of how this contact opted in. Every field is NULL MEANS UNKNOWN \u2014 we do not hold the record \u2014 and never \"no consent was given\", which is the opposite claim and not one we can make on your behalf. Set it when you import from another provider so your lawful basis moves with your contacts.",
                                                            "properties": {
                                                                "at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When they opted in, as recorded by whoever collected it. NULL MEANS UNKNOWN."
                                                                },
                                                                "ip": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The address the opt-in came from. NULL MEANS UNKNOWN."
                                                                },
                                                                "source": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Where: a form name, a URL, \"imported from Mailchimp\". Free text rather than an enum, because the shapes this takes across providers are not enumerable and an enum would force the evidence to be discarded to fit. NULL MEANS UNKNOWN."
                                                                }
                                                            }
                                                        },
                                                        "source": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "How this contact arrived. Free-form, not an enum: any string up to 50 characters is accepted on create. The values we set ourselves are `manual`, `import_api` and `import_csv`. `null` means NONE \u2014 nothing was recorded \u2014 not \"we did not look\" and not \"we do not know where they came from\": a contact created through this API is stamped `manual` when you send no `source`, and an import stamps its own, so a null here is a row that predates the column or one a caller explicitly cleared."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "operationId": "putContactsContact",
                "summary": "Update a contact",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "description": "The contact identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the contact."
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "Lower-cased and trimmed on write, so the address you read back may not be byte-identical to the one you sent."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The contact's display name. `null` means NONE \u2014 an address is all a contact needs, the column is nullable and neither create nor import requires one. It is not \"we did not look\": the name is on the row we already read. `{{ name }}` renders as the empty string for these contacts unless the template supplies its own inline fallback \u2014 a contact-field default cannot fill it, because `name` is a reserved key applied after the defaults are merged."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "subscribed",
                                                                "unsubscribed",
                                                                "bounced",
                                                                "complained",
                                                                "suppressed"
                                                            ],
                                                            "description": "The answer to \"will this contact be mailed\". `subscribed` is exactly \"we will attempt delivery\"; every other value is the reason we will not. DERIVED, and read-only \u2014 it reconciles the writable `status` field with the organization-wide suppression list, which are two independent gates that can and do disagree: `status` is read when a campaign's recipient set is built, the suppression list is read at send time per message, and nothing keeps them in step. A contact whose `status` says `subscribed` but whose address \u2014 or whose whole domain \u2014 is suppressed reads `suppressed` here, and no message will leave. The contact's own recorded decision outranks the list, so somebody who unsubscribed reads `unsubscribed` even when both are true of them. A stored status we do not recognise reads `unsubscribed`, never `subscribed`: guessing \"mailable\" from a value we cannot read is how people get mailed who asked not to be. **`status` is the separate, writable field**, and it accepts only `subscribed`, `unsubscribed`, `bounced` and `complained` \u2014 `suppressed` is not something you can set on a contact, it is something the suppression list does to them, which is why the two have different names. Note that `GET /contacts?status=` filters the stored column, not this field."
                                                        },
                                                        "fields": {
                                                            "type": "object",
                                                            "additionalProperties": {
                                                                "type": "string"
                                                            },
                                                            "description": "Custom field values, keyed by the field `key` that `GET /contact-fields` publishes and that `{{ signup_date }}` resolves \u2014 NEVER by a `contact_field` id, which identifies the definition and appears only as that resource's `id`. **Always an object**: `{}` when the contact has no values, never a list. Free-form \u2014 a key written through the API or an import with no `contact_field` definition behind it is still a real value on the contact and is included here; `GET /contacts/attribute-keys` is where you learn which keys are declared. Values are strings as stored: a field's `type` is an editing hint, not a storage type, and nothing is coerced. Field `default_value`s are NOT merged in \u2014 they are applied at send time, and merging them here would turn a default into a real value on your next write. The matching INPUT key is still spelled `attributes`."
                                                        },
                                                        "lists": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "The contact lists this contact belongs to, NAMED, so you do not have to fetch each one to display it \u2014 every path that returns a contact already loads them. They carry no `contact_count`: that is a property of the LIST, not of this membership, and `contact_list.contact_count` is where it is published. `null` means UNKNOWN \u2014 the membership pivot was not loaded for this response \u2014 and never `[]`, which would claim the contact belongs to no list. **The matching INPUT key is still spelled `list_ids`** and still takes bare ids, on create and on update."
                                                        },
                                                        "tags": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "Your own labels on this contact, NAMED. A tag is something you put on a contact and it stays there; a SEGMENT is a rule re-evaluated every time it is read, so its membership changes without anybody editing a contact. They are separate resources here for that reason. No `contact_count`: that belongs to the tag rather than to this contact having it, and `GET /contact-tags` publishes it. `null` means UNKNOWN \u2014 the relation was not loaded \u2014 never that this contact is untagged."
                                                        },
                                                        "interests": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "description": "What this contact CHOSE \u2014 the answers they ticked on a form, as opposed to `tags`, which are labels you put on them and they never see. Each carries the question it answers, because an answer name is meaningless without it and two groups may share one. `null` MEANS NOT INCLUDED \u2014 the relation was not loaded on this response. An empty array means the contact chose nothing, which is a different fact.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Match on this in a segment rule, never on the name."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "description": "The answer, as the contact read it."
                                                                    },
                                                                    "category_id": {
                                                                        "type": "string",
                                                                        "description": "The question this answers."
                                                                    },
                                                                    "category_title": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The question in words. `null` MEANS NOT INCLUDED \u2014 the category was not loaded, never that the question has no title."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "consent": {
                                                            "type": "object",
                                                            "description": "Evidence of how this contact opted in. Every field is NULL MEANS UNKNOWN \u2014 we do not hold the record \u2014 and never \"no consent was given\", which is the opposite claim and not one we can make on your behalf. Set it when you import from another provider so your lawful basis moves with your contacts.",
                                                            "properties": {
                                                                "at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When they opted in, as recorded by whoever collected it. NULL MEANS UNKNOWN."
                                                                },
                                                                "ip": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The address the opt-in came from. NULL MEANS UNKNOWN."
                                                                },
                                                                "source": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Where: a form name, a URL, \"imported from Mailchimp\". Free text rather than an enum, because the shapes this takes across providers are not enumerable and an enum would force the evidence to be discarded to fit. NULL MEANS UNKNOWN."
                                                                }
                                                            }
                                                        },
                                                        "source": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "How this contact arrived. Free-form, not an enum: any string up to 50 characters is accepted on create. The values we set ourselves are `manual`, `import_api` and `import_csv`. `null` means NONE \u2014 nothing was recorded \u2014 not \"we did not look\" and not \"we do not know where they came from\": a contact created through this API is stamped `manual` when you send no `source`, and an import stamps its own, so a null here is a row that predates the column or one a caller explicitly cleared."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "operationId": "patchContactsContact",
                "summary": "Update a contact",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "description": "The contact identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the contact."
                                                        },
                                                        "email": {
                                                            "type": "string",
                                                            "format": "email",
                                                            "description": "Lower-cased and trimmed on write, so the address you read back may not be byte-identical to the one you sent."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The contact's display name. `null` means NONE \u2014 an address is all a contact needs, the column is nullable and neither create nor import requires one. It is not \"we did not look\": the name is on the row we already read. `{{ name }}` renders as the empty string for these contacts unless the template supplies its own inline fallback \u2014 a contact-field default cannot fill it, because `name` is a reserved key applied after the defaults are merged."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "subscribed",
                                                                "unsubscribed",
                                                                "bounced",
                                                                "complained",
                                                                "suppressed"
                                                            ],
                                                            "description": "The answer to \"will this contact be mailed\". `subscribed` is exactly \"we will attempt delivery\"; every other value is the reason we will not. DERIVED, and read-only \u2014 it reconciles the writable `status` field with the organization-wide suppression list, which are two independent gates that can and do disagree: `status` is read when a campaign's recipient set is built, the suppression list is read at send time per message, and nothing keeps them in step. A contact whose `status` says `subscribed` but whose address \u2014 or whose whole domain \u2014 is suppressed reads `suppressed` here, and no message will leave. The contact's own recorded decision outranks the list, so somebody who unsubscribed reads `unsubscribed` even when both are true of them. A stored status we do not recognise reads `unsubscribed`, never `subscribed`: guessing \"mailable\" from a value we cannot read is how people get mailed who asked not to be. **`status` is the separate, writable field**, and it accepts only `subscribed`, `unsubscribed`, `bounced` and `complained` \u2014 `suppressed` is not something you can set on a contact, it is something the suppression list does to them, which is why the two have different names. Note that `GET /contacts?status=` filters the stored column, not this field."
                                                        },
                                                        "fields": {
                                                            "type": "object",
                                                            "additionalProperties": {
                                                                "type": "string"
                                                            },
                                                            "description": "Custom field values, keyed by the field `key` that `GET /contact-fields` publishes and that `{{ signup_date }}` resolves \u2014 NEVER by a `contact_field` id, which identifies the definition and appears only as that resource's `id`. **Always an object**: `{}` when the contact has no values, never a list. Free-form \u2014 a key written through the API or an import with no `contact_field` definition behind it is still a real value on the contact and is included here; `GET /contacts/attribute-keys` is where you learn which keys are declared. Values are strings as stored: a field's `type` is an editing hint, not a storage type, and nothing is coerced. Field `default_value`s are NOT merged in \u2014 they are applied at send time, and merging them here would turn a default into a real value on your next write. The matching INPUT key is still spelled `attributes`."
                                                        },
                                                        "lists": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "The contact lists this contact belongs to, NAMED, so you do not have to fetch each one to display it \u2014 every path that returns a contact already loads them. They carry no `contact_count`: that is a property of the LIST, not of this membership, and `contact_list.contact_count` is where it is published. `null` means UNKNOWN \u2014 the membership pivot was not loaded for this response \u2014 and never `[]`, which would claim the contact belongs to no list. **The matching INPUT key is still spelled `list_ids`** and still takes bare ids, on create and on update."
                                                        },
                                                        "tags": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    }
                                                                }
                                                            },
                                                            "description": "Your own labels on this contact, NAMED. A tag is something you put on a contact and it stays there; a SEGMENT is a rule re-evaluated every time it is read, so its membership changes without anybody editing a contact. They are separate resources here for that reason. No `contact_count`: that belongs to the tag rather than to this contact having it, and `GET /contact-tags` publishes it. `null` means UNKNOWN \u2014 the relation was not loaded \u2014 never that this contact is untagged."
                                                        },
                                                        "interests": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "description": "What this contact CHOSE \u2014 the answers they ticked on a form, as opposed to `tags`, which are labels you put on them and they never see. Each carries the question it answers, because an answer name is meaningless without it and two groups may share one. `null` MEANS NOT INCLUDED \u2014 the relation was not loaded on this response. An empty array means the contact chose nothing, which is a different fact.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Match on this in a segment rule, never on the name."
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "description": "The answer, as the contact read it."
                                                                    },
                                                                    "category_id": {
                                                                        "type": "string",
                                                                        "description": "The question this answers."
                                                                    },
                                                                    "category_title": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The question in words. `null` MEANS NOT INCLUDED \u2014 the category was not loaded, never that the question has no title."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "consent": {
                                                            "type": "object",
                                                            "description": "Evidence of how this contact opted in. Every field is NULL MEANS UNKNOWN \u2014 we do not hold the record \u2014 and never \"no consent was given\", which is the opposite claim and not one we can make on your behalf. Set it when you import from another provider so your lawful basis moves with your contacts.",
                                                            "properties": {
                                                                "at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When they opted in, as recorded by whoever collected it. NULL MEANS UNKNOWN."
                                                                },
                                                                "ip": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The address the opt-in came from. NULL MEANS UNKNOWN."
                                                                },
                                                                "source": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Where: a form name, a URL, \"imported from Mailchimp\". Free text rather than an enum, because the shapes this takes across providers are not enumerable and an enum would force the evidence to be discarded to fit. NULL MEANS UNKNOWN."
                                                                }
                                                            }
                                                        },
                                                        "source": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "How this contact arrived. Free-form, not an enum: any string up to 50 characters is accepted on create. The values we set ourselves are `manual`, `import_api` and `import_csv`. `null` means NONE \u2014 nothing was recorded \u2014 not \"we did not look\" and not \"we do not know where they came from\": a contact created through this API is stamped `manual` when you send no `source`, and an import stamps its own, so a null here is a row that predates the column or one a caller explicitly cleared."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteContactsContact",
                "summary": "Delete a contact",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "description": "The contact identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. The contact is gone; the confirmation is the envelope message."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contact-lists": {
            "get": {
                "operationId": "getContactLists",
                "summary": "List contact lists",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "contact_list"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Unique identifier for the list."
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Optional free text describing what the list is for. `null` means NONE \u2014 none was written \u2014 never \"we did not include it\": it is a column on the row already read and it is present in a list response as well as on a single list. Nothing in the send path reads it \u2014 it is stored and handed back for your own operators."
                                                                    },
                                                                    "contact_count": {
                                                                        "type": "integer",
                                                                        "description": "EVERY member of the list, whatever their state. An unsubscribed contact is still a member \u2014 membership and deliverability are separate facts here, and removing somebody from a list is not how an unsubscribe is recorded. So a list of 500 with 40 unsubscribes still reports 500; the mailable subset is `GET /contacts?list_id=\u2026` filtered on `state`. Never null: the count is either already on the model or taken live."
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    },
                                                                    "updated_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postContactLists",
                "summary": "Create a contact list",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_list"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the list."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Optional free text describing what the list is for. `null` means NONE \u2014 none was written \u2014 never \"we did not include it\": it is a column on the row already read and it is present in a list response as well as on a single list. Nothing in the send path reads it \u2014 it is stored and handed back for your own operators."
                                                        },
                                                        "contact_count": {
                                                            "type": "integer",
                                                            "description": "EVERY member of the list, whatever their state. An unsubscribed contact is still a member \u2014 membership and deliverability are separate facts here, and removing somebody from a list is not how an unsubscribe is recorded. So a list of 500 with 40 unsubscribes still reports 500; the mailable subset is `GET /contacts?list_id=\u2026` filtered on `state`. Never null: the count is either already on the model or taken live."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contact-lists/{contact_list}": {
            "get": {
                "operationId": "getContactListsContactList",
                "summary": "Retrieve a contact list",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact_list",
                        "in": "path",
                        "required": true,
                        "description": "The contact list identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_list"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the list."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Optional free text describing what the list is for. `null` means NONE \u2014 none was written \u2014 never \"we did not include it\": it is a column on the row already read and it is present in a list response as well as on a single list. Nothing in the send path reads it \u2014 it is stored and handed back for your own operators."
                                                        },
                                                        "contact_count": {
                                                            "type": "integer",
                                                            "description": "EVERY member of the list, whatever their state. An unsubscribed contact is still a member \u2014 membership and deliverability are separate facts here, and removing somebody from a list is not how an unsubscribe is recorded. So a list of 500 with 40 unsubscribes still reports 500; the mailable subset is `GET /contacts?list_id=\u2026` filtered on `state`. Never null: the count is either already on the model or taken live."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "operationId": "putContactListsContactList",
                "summary": "Update a contact list",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact_list",
                        "in": "path",
                        "required": true,
                        "description": "The contact list identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_list"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the list."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Optional free text describing what the list is for. `null` means NONE \u2014 none was written \u2014 never \"we did not include it\": it is a column on the row already read and it is present in a list response as well as on a single list. Nothing in the send path reads it \u2014 it is stored and handed back for your own operators."
                                                        },
                                                        "contact_count": {
                                                            "type": "integer",
                                                            "description": "EVERY member of the list, whatever their state. An unsubscribed contact is still a member \u2014 membership and deliverability are separate facts here, and removing somebody from a list is not how an unsubscribe is recorded. So a list of 500 with 40 unsubscribes still reports 500; the mailable subset is `GET /contacts?list_id=\u2026` filtered on `state`. Never null: the count is either already on the model or taken live."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "operationId": "patchContactListsContactList",
                "summary": "Update a contact list",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact_list",
                        "in": "path",
                        "required": true,
                        "description": "The contact list identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_list"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the list."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Optional free text describing what the list is for. `null` means NONE \u2014 none was written \u2014 never \"we did not include it\": it is a column on the row already read and it is present in a list response as well as on a single list. Nothing in the send path reads it \u2014 it is stored and handed back for your own operators."
                                                        },
                                                        "contact_count": {
                                                            "type": "integer",
                                                            "description": "EVERY member of the list, whatever their state. An unsubscribed contact is still a member \u2014 membership and deliverability are separate facts here, and removing somebody from a list is not how an unsubscribe is recorded. So a list of 500 with 40 unsubscribes still reports 500; the mailable subset is `GET /contacts?list_id=\u2026` filtered on `state`. Never null: the count is either already on the model or taken live."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteContactListsContactList",
                "summary": "Delete a contact list",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact_list",
                        "in": "path",
                        "required": true,
                        "description": "The contact list identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. The list is gone; its members are not \u2014 deleting a list does not delete the contacts on it."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contact-lists/{contactList}/members": {
            "post": {
                "operationId": "postContactListsContactListMembers",
                "summary": "Members a contact list",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contactList",
                        "in": "path",
                        "required": true,
                        "description": "The contact list identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "ONE shape for both directions \u2014 adding members and removing one answer the same five counters, with the irrelevant ones at zero \u2014 so a caller writing a \"sync my list\" routine never has to branch on which call it just made.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_list_membership"
                                                            ]
                                                        },
                                                        "list_id": {
                                                            "type": "string",
                                                            "description": "The list this happened to, echoed from the path so the response can be logged on its own."
                                                        },
                                                        "added": {
                                                            "type": "integer",
                                                            "description": "Newly attached. Re-adding an existing member is a no-op that still counts as added \u2014 the request \"this contact is on this list\" was satisfied either way. Zero on a removal."
                                                        },
                                                        "removed": {
                                                            "type": "integer",
                                                            "description": "Detached. Removing somebody who was not a member is a no-op and counts 0. Zero on an add."
                                                        },
                                                        "skipped": {
                                                            "type": "integer",
                                                            "description": "Ids that resolved to nothing in this organization. Both endpoints quietly ignore ids they cannot see \u2014 answering \"no such contact\" would confirm which ids exist in someone else's account \u2014 so without this counter a caller submitting 500 ids and having 40 ignored would have no way to know. It does not name them, for the same reason."
                                                        },
                                                        "contact_count": {
                                                            "type": "integer",
                                                            "description": "The size of the list AFTER the change, so you never have to follow up with a GET. Counts every member whatever their state, exactly as `contact_list.contact_count` does."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contact-lists/{contactList}/members/{contact}": {
            "delete": {
                "operationId": "deleteContactListsContactListMembersContact",
                "summary": "Delete a contact list",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contactList",
                        "in": "path",
                        "required": true,
                        "description": "The contact list identifier.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "description": "The contact identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "ONE shape for both directions \u2014 adding members and removing one answer the same five counters, with the irrelevant ones at zero \u2014 so a caller writing a \"sync my list\" routine never has to branch on which call it just made.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_list_membership"
                                                            ]
                                                        },
                                                        "list_id": {
                                                            "type": "string",
                                                            "description": "The list this happened to, echoed from the path so the response can be logged on its own."
                                                        },
                                                        "added": {
                                                            "type": "integer",
                                                            "description": "Newly attached. Re-adding an existing member is a no-op that still counts as added \u2014 the request \"this contact is on this list\" was satisfied either way. Zero on a removal."
                                                        },
                                                        "removed": {
                                                            "type": "integer",
                                                            "description": "Detached. Removing somebody who was not a member is a no-op and counts 0. Zero on an add."
                                                        },
                                                        "skipped": {
                                                            "type": "integer",
                                                            "description": "Ids that resolved to nothing in this organization. Both endpoints quietly ignore ids they cannot see \u2014 answering \"no such contact\" would confirm which ids exist in someone else's account \u2014 so without this counter a caller submitting 500 ids and having 40 ignored would have no way to know. It does not name them, for the same reason."
                                                        },
                                                        "contact_count": {
                                                            "type": "integer",
                                                            "description": "The size of the list AFTER the change, so you never have to follow up with a GET. Counts every member whatever their state, exactly as `contact_list.contact_count` does."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contact-tags": {
            "get": {
                "operationId": "getContactTags",
                "summary": "List contact tags",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "contact_tag"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "description": "Unique identifier for the tag."
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "description": "The label as it was first written. Tags are matched case-insensitively \u2014 \"VIP\" and \"vip\" are one tag \u2014 and the spelling kept is whichever was used first, so a contact never shows two chips for the same label."
                                                            },
                                                            "contact_count": {
                                                                "type": "integer",
                                                                "nullable": true,
                                                                "description": "How many contacts carry this tag. NULL MEANS NOT INCLUDED \u2014 this response did not count them \u2014 never that the tag is unused. It is present when listing tags and absent when a tag is returned as part of a contact, where counting every tag would cost a query per chip."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postContactTags",
                "summary": "Create a contact tag",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_tag"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the tag."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "description": "The label as it was first written. Tags are matched case-insensitively \u2014 \"VIP\" and \"vip\" are one tag \u2014 and the spelling kept is whichever was used first, so a contact never shows two chips for the same label."
                                                        },
                                                        "contact_count": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "How many contacts carry this tag. NULL MEANS NOT INCLUDED \u2014 this response did not count them \u2014 never that the tag is unused. It is present when listing tags and absent when a tag is returned as part of a contact, where counting every tag would cost a query per chip."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contact-tags/{tag}": {
            "delete": {
                "operationId": "deleteContactTagsTag",
                "summary": "Delete a contact tag",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "tag",
                        "in": "path",
                        "required": true,
                        "description": "The tag identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. The tag is removed from every contact that carried it; the contacts themselves are untouched."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contacts/{contact}/tags": {
            "post": {
                "operationId": "postContactsContactTags",
                "summary": "Tags a contact",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "description": "The contact identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "contact_tag"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "description": "Unique identifier for the tag."
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "description": "The label as it was first written. Tags are matched case-insensitively \u2014 \"VIP\" and \"vip\" are one tag \u2014 and the spelling kept is whichever was used first, so a contact never shows two chips for the same label."
                                                            },
                                                            "contact_count": {
                                                                "type": "integer",
                                                                "nullable": true,
                                                                "description": "How many contacts carry this tag. NULL MEANS NOT INCLUDED \u2014 this response did not count them \u2014 never that the tag is unused. It is present when listing tags and absent when a tag is returned as part of a contact, where counting every tag would cost a query per chip."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/interest-categories": {
            "get": {
                "operationId": "getInterestCategories",
                "summary": "List interest categorys",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "interest_category"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string"
                                                            },
                                                            "title": {
                                                                "type": "string",
                                                                "description": "The question, as a contact reads it on a signup form \u2014 usually phrased as one: \"What do you want to hear about?\""
                                                            },
                                                            "type": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "checkboxes",
                                                                    "dropdown",
                                                                    "radio",
                                                                    "hidden"
                                                                ],
                                                                "description": "How the group renders on a form. THIS IS PRESENTATION, NOT ENFORCEMENT: a `radio` group with two interests selected is a form that was bypassed, not a rejected write, because refusing it would lose data we already hold rather than fix the form. `hidden` keeps the group off the form entirely so it can only be set through the API, which is how an internal classification lives beside the ones a contact chooses."
                                                            },
                                                            "display_order": {
                                                                "type": "integer",
                                                                "description": "Position on the form, lower first."
                                                            },
                                                            "interests": {
                                                                "type": "array",
                                                                "nullable": true,
                                                                "items": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "id": {
                                                                            "type": "string"
                                                                        },
                                                                        "name": {
                                                                            "type": "string"
                                                                        },
                                                                        "display_order": {
                                                                            "type": "integer"
                                                                        }
                                                                    }
                                                                },
                                                                "description": "The answers a contact can choose. Returned WITH the category because they are read as one thing \u2014 a form section \u2014 and fetching them separately would be two round trips to render one block of checkboxes. `null` means UNKNOWN: the relation was not loaded, never that the category has no answers."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postInterestCategories",
                "summary": "Create a interest category",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "interest_category"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string"
                                                        },
                                                        "title": {
                                                            "type": "string",
                                                            "description": "The question, as a contact reads it on a signup form \u2014 usually phrased as one: \"What do you want to hear about?\""
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "checkboxes",
                                                                "dropdown",
                                                                "radio",
                                                                "hidden"
                                                            ],
                                                            "description": "How the group renders on a form. THIS IS PRESENTATION, NOT ENFORCEMENT: a `radio` group with two interests selected is a form that was bypassed, not a rejected write, because refusing it would lose data we already hold rather than fix the form. `hidden` keeps the group off the form entirely so it can only be set through the API, which is how an internal classification lives beside the ones a contact chooses."
                                                        },
                                                        "display_order": {
                                                            "type": "integer",
                                                            "description": "Position on the form, lower first."
                                                        },
                                                        "interests": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string"
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    },
                                                                    "display_order": {
                                                                        "type": "integer"
                                                                    }
                                                                }
                                                            },
                                                            "description": "The answers a contact can choose. Returned WITH the category because they are read as one thing \u2014 a form section \u2014 and fetching them separately would be two round trips to render one block of checkboxes. `null` means UNKNOWN: the relation was not loaded, never that the category has no answers."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/interest-categories/{category}": {
            "delete": {
                "operationId": "deleteInterestCategoriesCategory",
                "summary": "Delete a interest category",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "category",
                        "in": "path",
                        "required": true,
                        "description": "The category identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. The category, its interests and every contact's answers to it are removed \u2014 once the question is gone there is nothing for an answer to be an answer to."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contacts/{contact}/interests": {
            "put": {
                "operationId": "putContactsContactInterests",
                "summary": "Interests a contact",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "description": "The contact identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "interest"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string"
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "description": "The answer, as a contact reads it."
                                                            },
                                                            "category": {
                                                                "type": "object",
                                                                "description": "The question this answers. Included because an answer alone is ambiguous \u2014 \"Events\" means nothing until you know which question it belongs to.",
                                                                "properties": {
                                                                    "id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "NULL MEANS UNKNOWN \u2014 the category relation was not loaded."
                                                                    },
                                                                    "title": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "NULL MEANS UNKNOWN \u2014 the category relation was not loaded."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/contact-fields": {
            "get": {
                "operationId": "getContactFields",
                "summary": "List contact fields",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "description": "One usable key of a contact's `fields` object. Serves both `GET /contact-fields` (the declared catalog) and `GET /contacts/attribute-keys` (the catalog plus keys observed on contact data), which is why `declared` exists.",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "contact_field"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "The definition's id, for `PUT`/`DELETE /contact-fields/{field}`. `null` when `declared` is false \u2014 there is no definition row, so there is nothing to address."
                                                            },
                                                            "key": {
                                                                "type": "string",
                                                                "description": "The stable name. This is the key inside a contact's `fields` object and the `{{ signup_date }}` tag in campaign content. Contact values are keyed by this, never by `id`."
                                                            },
                                                            "declared": {
                                                                "type": "boolean",
                                                                "description": "Whether this organization has DEFINED the key, or we merely observed it on contact data. Both are usable in content and in segment rules; only a declared one has a stored label, type and default. Every write path registers a definition for a key it has not seen before \u2014 `POST`, `PATCH` and `PUT /contacts` as well as `POST /contacts/import` \u2014 so which endpoint wrote a key no longer decides which side of this line it lands on. An undeclared key is one that arrived before that was true, or one whose name is not a legal key."
                                                            },
                                                            "label": {
                                                                "type": "string",
                                                                "description": "Display name. Derived from the key for an undeclared one."
                                                            },
                                                            "type": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "text",
                                                                    "number",
                                                                    "date",
                                                                    "boolean"
                                                                ],
                                                                "description": "How a value should be EDITED and displayed. Not a storage type: every value in a contact's `fields` object is a string whatever this says, and nothing is coerced."
                                                            },
                                                            "required": {
                                                                "type": "boolean",
                                                                "description": "Whether every contact must carry a value. Enforced in two places and only two: a contact being CREATED must supply it, and an update may not CLEAR a value that was already there. It is never checked retroactively, so marking a field required does not start failing your sync on contacts that predate the decision \u2014 which is the only way anyone could safely turn it on for a live audience. `default_value` does not satisfy it: the default is a render-time placeholder, and accepting a placeholder for a field you marked required is the opposite of what you asked for. Always false for an undeclared key."
                                                            },
                                                            "default_value": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "Substituted at send time for contacts with no value of their own. It is never written into a contact's `fields`."
                                                            },
                                                            "help_text": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "The hint shown beside this field on a form. `null` MEANS NONE WAS WRITTEN \u2014 it carries no behaviour, so an absent hint changes nothing about what the field accepts."
                                                            },
                                                            "contacts_with_value": {
                                                                "type": "integer",
                                                                "description": "How many contacts carry a non-empty value for this key \u2014 the \"is it safe to delete this\" signal. Always an integer."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true,
                                                                "description": "`null` when `declared` is false: an observed key has no definition row and therefore no creation time. Genuinely unknown, not zero."
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postContactFields",
                "summary": "Create a contact field",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "One usable key of a contact's `fields` object. Serves both `GET /contact-fields` (the declared catalog) and `GET /contacts/attribute-keys` (the catalog plus keys observed on contact data), which is why `declared` exists.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_field"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The definition's id, for `PUT`/`DELETE /contact-fields/{field}`. `null` when `declared` is false \u2014 there is no definition row, so there is nothing to address."
                                                        },
                                                        "key": {
                                                            "type": "string",
                                                            "description": "The stable name. This is the key inside a contact's `fields` object and the `{{ signup_date }}` tag in campaign content. Contact values are keyed by this, never by `id`."
                                                        },
                                                        "declared": {
                                                            "type": "boolean",
                                                            "description": "Whether this organization has DEFINED the key, or we merely observed it on contact data. Both are usable in content and in segment rules; only a declared one has a stored label, type and default. Every write path registers a definition for a key it has not seen before \u2014 `POST`, `PATCH` and `PUT /contacts` as well as `POST /contacts/import` \u2014 so which endpoint wrote a key no longer decides which side of this line it lands on. An undeclared key is one that arrived before that was true, or one whose name is not a legal key."
                                                        },
                                                        "label": {
                                                            "type": "string",
                                                            "description": "Display name. Derived from the key for an undeclared one."
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "text",
                                                                "number",
                                                                "date",
                                                                "boolean"
                                                            ],
                                                            "description": "How a value should be EDITED and displayed. Not a storage type: every value in a contact's `fields` object is a string whatever this says, and nothing is coerced."
                                                        },
                                                        "required": {
                                                            "type": "boolean",
                                                            "description": "Whether every contact must carry a value. Enforced in two places and only two: a contact being CREATED must supply it, and an update may not CLEAR a value that was already there. It is never checked retroactively, so marking a field required does not start failing your sync on contacts that predate the decision \u2014 which is the only way anyone could safely turn it on for a live audience. `default_value` does not satisfy it: the default is a render-time placeholder, and accepting a placeholder for a field you marked required is the opposite of what you asked for. Always false for an undeclared key."
                                                        },
                                                        "default_value": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Substituted at send time for contacts with no value of their own. It is never written into a contact's `fields`."
                                                        },
                                                        "help_text": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The hint shown beside this field on a form. `null` MEANS NONE WAS WRITTEN \u2014 it carries no behaviour, so an absent hint changes nothing about what the field accepts."
                                                        },
                                                        "contacts_with_value": {
                                                            "type": "integer",
                                                            "description": "How many contacts carry a non-empty value for this key \u2014 the \"is it safe to delete this\" signal. Always an integer."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "`null` when `declared` is false: an observed key has no definition row and therefore no creation time. Genuinely unknown, not zero."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Declares one key of a contact's `fields` object: its label, its type, whether it is\nrequired, the value to fall back on and the hint to show beside it.\n\n**Declaring is optional.** A contact may carry any attribute key you write, declared or not,\nand an undeclared key works in content and in segment rules exactly the same. What a\ndeclaration adds is a label, a default at send time, a place in the field picker, and the\noption of requiring it. `declared` on the field object tells you which kind you are looking\nat.\n\n**`required` is enforced in two places and only two.** A contact being CREATED must supply\nit, and an update may not CLEAR a value that was already there. It is never checked\nretroactively, so marking a long-standing field required does not start rejecting contacts\nthat predate the decision \u2014 which is the only way anyone could safely turn it on for a live\naudience. In an import, a row with no value for a required field comes back in `errors[]`\nwith reason `missing_required_field`; the rest of the file still imports.\n\n**`default_value` does not satisfy `required`.** The default is substituted at render time\nfor a contact who has no value of their own and is never written to the contact. Accepting a\nplaceholder for a field you marked required would be the opposite of what you asked for.\n\nAn organization may hold 100 field definitions. The 101st is refused with the count and the\ncap in the message.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "label"
                                ],
                                "properties": {
                                    "label": {
                                        "type": "string",
                                        "maxLength": 120,
                                        "description": "The display name."
                                    },
                                    "key": {
                                        "type": "string",
                                        "maxLength": 64,
                                        "description": "The stable name \u2014 the key inside a contact's `fields` and the `{{ tag }}` in content. Lowercase letters, numbers and underscores, starting with a letter. Omit it and we derive one from the label (\"Signup Date\" \u2192 `signup_date`). It cannot be changed afterwards: content and contact data both reference it."
                                    },
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "text",
                                            "number",
                                            "date",
                                            "boolean"
                                        ],
                                        "description": "How a value should be EDITED and displayed. Not a storage type \u2014 every value is a string whatever this says, and nothing is coerced."
                                    },
                                    "required": {
                                        "type": "boolean",
                                        "description": "Whether every contact must carry a value. Defaults to false."
                                    },
                                    "default_value": {
                                        "type": "string",
                                        "maxLength": 500,
                                        "description": "Substituted at send time for a contact with no value of their own. Never written to the contact."
                                    },
                                    "help_text": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "The hint shown beside the input on a form. No behaviour."
                                    }
                                }
                            },
                            "example": {
                                "label": "Company",
                                "type": "text",
                                "required": true,
                                "help_text": "The organisation they work for"
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/contact-fields/{field}": {
            "put": {
                "operationId": "putContactFieldsField",
                "summary": "Update a contact field",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "field",
                        "in": "path",
                        "required": true,
                        "description": "The field identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "One usable key of a contact's `fields` object. Serves both `GET /contact-fields` (the declared catalog) and `GET /contacts/attribute-keys` (the catalog plus keys observed on contact data), which is why `declared` exists.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "contact_field"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The definition's id, for `PUT`/`DELETE /contact-fields/{field}`. `null` when `declared` is false \u2014 there is no definition row, so there is nothing to address."
                                                        },
                                                        "key": {
                                                            "type": "string",
                                                            "description": "The stable name. This is the key inside a contact's `fields` object and the `{{ signup_date }}` tag in campaign content. Contact values are keyed by this, never by `id`."
                                                        },
                                                        "declared": {
                                                            "type": "boolean",
                                                            "description": "Whether this organization has DEFINED the key, or we merely observed it on contact data. Both are usable in content and in segment rules; only a declared one has a stored label, type and default. Every write path registers a definition for a key it has not seen before \u2014 `POST`, `PATCH` and `PUT /contacts` as well as `POST /contacts/import` \u2014 so which endpoint wrote a key no longer decides which side of this line it lands on. An undeclared key is one that arrived before that was true, or one whose name is not a legal key."
                                                        },
                                                        "label": {
                                                            "type": "string",
                                                            "description": "Display name. Derived from the key for an undeclared one."
                                                        },
                                                        "type": {
                                                            "type": "string",
                                                            "enum": [
                                                                "text",
                                                                "number",
                                                                "date",
                                                                "boolean"
                                                            ],
                                                            "description": "How a value should be EDITED and displayed. Not a storage type: every value in a contact's `fields` object is a string whatever this says, and nothing is coerced."
                                                        },
                                                        "required": {
                                                            "type": "boolean",
                                                            "description": "Whether every contact must carry a value. Enforced in two places and only two: a contact being CREATED must supply it, and an update may not CLEAR a value that was already there. It is never checked retroactively, so marking a field required does not start failing your sync on contacts that predate the decision \u2014 which is the only way anyone could safely turn it on for a live audience. `default_value` does not satisfy it: the default is a render-time placeholder, and accepting a placeholder for a field you marked required is the opposite of what you asked for. Always false for an undeclared key."
                                                        },
                                                        "default_value": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Substituted at send time for contacts with no value of their own. It is never written into a contact's `fields`."
                                                        },
                                                        "help_text": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The hint shown beside this field on a form. `null` MEANS NONE WAS WRITTEN \u2014 it carries no behaviour, so an absent hint changes nothing about what the field accepts."
                                                        },
                                                        "contacts_with_value": {
                                                            "type": "integer",
                                                            "description": "How many contacts carry a non-empty value for this key \u2014 the \"is it safe to delete this\" signal. Always an integer."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "`null` when `declared` is false: an observed key has no definition row and therefore no creation time. Genuinely unknown, not zero."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteContactFieldsField",
                "summary": "Delete a contact field",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "field",
                        "in": "path",
                        "required": true,
                        "description": "The field identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. The definition is gone; contacts keep any values stored under that key, which then read as an undeclared key."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/segments": {
            "get": {
                "operationId": "getSegments",
                "summary": "List segments",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "segment"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "description": "Unique identifier for the segment."
                                                            },
                                                            "name": {
                                                                "type": "string"
                                                            },
                                                            "description": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "Optional free text describing what the segment is for. `null` means NONE \u2014 none was written \u2014 never \"we did not include it\": it is a column on the row already read and it is present in a list response as well as on a single segment. It has no effect on the rules; `rules` is the definition."
                                                            },
                                                            "match": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "all",
                                                                    "any"
                                                                ],
                                                                "description": "How the rules combine: `all` of them must hold, or `any` one."
                                                            },
                                                            "rules": {
                                                                "type": "array",
                                                                "description": "The segment definition, round-tripped \u2014 this is your own input back, not an internal query representation. Anything outside these three keys is stripped before storage. The compiler that turns rules into SQL is not published and is free to change.",
                                                                "items": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "field": {
                                                                            "type": "string",
                                                                            "description": "A contact column (`email`, `name`, `status`), one of the engagement pseudo-fields (`opened`, `clicked`, `emailed`) read from the delivery-event ledger rather than from contact data, or any key of the contact's `fields` object, declared or not. Note that `status` here is the stored column, not the contact's derived `state`."
                                                                        },
                                                                        "op": {
                                                                            "type": "string",
                                                                            "enum": [
                                                                                "equals",
                                                                                "not_equals",
                                                                                "contains",
                                                                                "not_contains",
                                                                                "is_set",
                                                                                "is_not_set",
                                                                                "starts_with",
                                                                                "ends_with",
                                                                                "greater_than",
                                                                                "less_than",
                                                                                "before",
                                                                                "after",
                                                                                "within_days",
                                                                                "not_within_days"
                                                                            ],
                                                                            "description": "`within_days` / `not_within_days` pair ONLY with the engagement fields, and those fields pair only with them. `not_within_days` deliberately includes contacts never emailed at all. `greater_than` / `less_than` compare NUMBERS \u2014 a contact attribute is stored as text, so without the cast \"10\" would sort below \"9\" and a rule for more than 9 orders would exclude everybody with ten. `before` / `after` compare a date attribute as an absolute instant, unlike the rolling `within_days` window. `starts_with` / `ends_with` are not `contains`: an address AT acme.com and one mentioning acme.com anywhere are different audiences. A value these cannot parse \u2014 a non-numeric number, an unreadable date \u2014 matches NOTHING rather than everything, because a predicate we cannot evaluate must narrow the audience and never widen it."
                                                                        },
                                                                        "value": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "description": "Always present, unlike the stored rule, which omits the key entirely for operators that take no value. `null` for `is_set` / `is_not_set` \u2014 null rather than `\"\"`, which would read as \"equal to nothing\". A day count of 1\u2013365 for the engagement operators."
                                                                        }
                                                                    }
                                                                }
                                                            },
                                                            "contact_count": {
                                                                "type": "integer",
                                                                "description": "LIVE. A segment is a query, so this is what the rules match now, not what they matched when it was saved. Always an integer."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            },
                                                            "updated_at": {
                                                                "type": "string",
                                                                "format": "date-time"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postSegments",
                "summary": "Create a segment",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "segment"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the segment."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Optional free text describing what the segment is for. `null` means NONE \u2014 none was written \u2014 never \"we did not include it\": it is a column on the row already read and it is present in a list response as well as on a single segment. It has no effect on the rules; `rules` is the definition."
                                                        },
                                                        "match": {
                                                            "type": "string",
                                                            "enum": [
                                                                "all",
                                                                "any"
                                                            ],
                                                            "description": "How the rules combine: `all` of them must hold, or `any` one."
                                                        },
                                                        "rules": {
                                                            "type": "array",
                                                            "description": "The segment definition, round-tripped \u2014 this is your own input back, not an internal query representation. Anything outside these three keys is stripped before storage. The compiler that turns rules into SQL is not published and is free to change.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "field": {
                                                                        "type": "string",
                                                                        "description": "A contact column (`email`, `name`, `status`), one of the engagement pseudo-fields (`opened`, `clicked`, `emailed`) read from the delivery-event ledger rather than from contact data, or any key of the contact's `fields` object, declared or not. Note that `status` here is the stored column, not the contact's derived `state`."
                                                                    },
                                                                    "op": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "equals",
                                                                            "not_equals",
                                                                            "contains",
                                                                            "not_contains",
                                                                            "is_set",
                                                                            "is_not_set",
                                                                            "starts_with",
                                                                            "ends_with",
                                                                            "greater_than",
                                                                            "less_than",
                                                                            "before",
                                                                            "after",
                                                                            "within_days",
                                                                            "not_within_days"
                                                                        ],
                                                                        "description": "`within_days` / `not_within_days` pair ONLY with the engagement fields, and those fields pair only with them. `not_within_days` deliberately includes contacts never emailed at all. `greater_than` / `less_than` compare NUMBERS \u2014 a contact attribute is stored as text, so without the cast \"10\" would sort below \"9\" and a rule for more than 9 orders would exclude everybody with ten. `before` / `after` compare a date attribute as an absolute instant, unlike the rolling `within_days` window. `starts_with` / `ends_with` are not `contains`: an address AT acme.com and one mentioning acme.com anywhere are different audiences. A value these cannot parse \u2014 a non-numeric number, an unreadable date \u2014 matches NOTHING rather than everything, because a predicate we cannot evaluate must narrow the audience and never widen it."
                                                                    },
                                                                    "value": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Always present, unlike the stored rule, which omits the key entirely for operators that take no value. `null` for `is_set` / `is_not_set` \u2014 null rather than `\"\"`, which would read as \"equal to nothing\". A day count of 1\u2013365 for the engagement operators."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "contact_count": {
                                                            "type": "integer",
                                                            "description": "LIVE. A segment is a query, so this is what the rules match now, not what they matched when it was saved. Always an integer."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/segments/preview": {
            "post": {
                "operationId": "postSegmentsPreview",
                "summary": "Preview a segment",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "segment_preview"
                                                            ]
                                                        },
                                                        "count": {
                                                            "type": "integer",
                                                            "description": "Every contact the rules match \u2014 exact, and NOT the size of `sample`."
                                                        },
                                                        "sample": {
                                                            "type": "array",
                                                            "description": "At most five matches, in the query's own order, so an author can see the audience is the one they meant. It is a sample, not a page: there is no pagination and no promise about which five. Rows are not contact objects and carry no id \u2014 the preview query selects only these three columns; save the segment if you want the matching contacts.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "email": {
                                                                        "type": "string",
                                                                        "format": "email"
                                                                    },
                                                                    "name": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The contact's display name, read from the same column `contact.name` publishes. `null` means NONE \u2014 this contact has no name recorded \u2014 never \"the preview left it out\": `name` is one of the three columns the preview query selects, so it is always a real answer."
                                                                    },
                                                                    "state": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "subscribed",
                                                                            "unsubscribed",
                                                                            "bounced",
                                                                            "complained",
                                                                            "suppressed"
                                                                        ],
                                                                        "description": "Literally `contact.state`, resolved by the same code against the same suppression list, so a preview can never disagree with the contact endpoint about who is mailable."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "How many contacts a set of rules currently matches, and a sample of them, without saving the\nsegment. Call this before sending to one.\n\n**Rules take one of four kinds of field:**\n\n| Kind | Fields | Example |\n|---|---|---|\n| Contact columns | `email`, `name`, `status` | `{\"field\": \"email\", \"op\": \"ends_with\", \"value\": \"@acme.com\"}` |\n| Custom fields | any key from `GET /contact-fields` | `{\"field\": \"plan\", \"op\": \"equals\", \"value\": \"pro\"}` |\n| Engagement | `opened`, `clicked`, `emailed` | `{\"field\": \"opened\", \"op\": \"within_days\", \"value\": \"90\"}` |\n| **Membership** | `tag`, `interest` | `{\"field\": \"tag\", \"op\": \"equals\", \"value\": \"vip\"}` |\n\n**`tag` matches by NAME, `interest` matches by ID.** That asymmetry is deliberate. A tag is\nwritten by name everywhere \u2014 created on first use, case-insensitively \u2014 so a rule holding a\nULID would break the moment somebody renamed it. An interest is an answer to a question the\n*contact* was asked and its name is form copy, so rewording \"Product updates\" must not\nsilently empty every segment built on it.\n\nMembership fields take `equals`, `not_equals`, `is_set` (has any) and `is_not_set` (has\nnone). Deliberately **not** `contains`: a tag is on a contact or it is not, and a substring\nmatch over a set would let `contains \"vip\"` quietly also match `vip-churn-risk`.\n\n**`not_equals` means \"does not carry it\", not \"carries something else\".** A contact with\nboth `vip` and `churn-risk` is EXCLUDED by `tag is not vip` \u2014 they carry it. A contact with\nno tags at all is included, because they do not.\n\nA rule we cannot evaluate \u2014 an unparseable number or date, a blank tag \u2014 matches **nothing**.\nWidening is the dangerous direction: it mails people who were never meant to be in the\naudience, and it does so quietly."
            }
        },
        "/api/v1/segments/{segment}": {
            "put": {
                "operationId": "putSegmentsSegment",
                "summary": "Update a segment",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "segment",
                        "in": "path",
                        "required": true,
                        "description": "The segment identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "segment"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the segment."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Optional free text describing what the segment is for. `null` means NONE \u2014 none was written \u2014 never \"we did not include it\": it is a column on the row already read and it is present in a list response as well as on a single segment. It has no effect on the rules; `rules` is the definition."
                                                        },
                                                        "match": {
                                                            "type": "string",
                                                            "enum": [
                                                                "all",
                                                                "any"
                                                            ],
                                                            "description": "How the rules combine: `all` of them must hold, or `any` one."
                                                        },
                                                        "rules": {
                                                            "type": "array",
                                                            "description": "The segment definition, round-tripped \u2014 this is your own input back, not an internal query representation. Anything outside these three keys is stripped before storage. The compiler that turns rules into SQL is not published and is free to change.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "field": {
                                                                        "type": "string",
                                                                        "description": "A contact column (`email`, `name`, `status`), one of the engagement pseudo-fields (`opened`, `clicked`, `emailed`) read from the delivery-event ledger rather than from contact data, or any key of the contact's `fields` object, declared or not. Note that `status` here is the stored column, not the contact's derived `state`."
                                                                    },
                                                                    "op": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "equals",
                                                                            "not_equals",
                                                                            "contains",
                                                                            "not_contains",
                                                                            "is_set",
                                                                            "is_not_set",
                                                                            "starts_with",
                                                                            "ends_with",
                                                                            "greater_than",
                                                                            "less_than",
                                                                            "before",
                                                                            "after",
                                                                            "within_days",
                                                                            "not_within_days"
                                                                        ],
                                                                        "description": "`within_days` / `not_within_days` pair ONLY with the engagement fields, and those fields pair only with them. `not_within_days` deliberately includes contacts never emailed at all. `greater_than` / `less_than` compare NUMBERS \u2014 a contact attribute is stored as text, so without the cast \"10\" would sort below \"9\" and a rule for more than 9 orders would exclude everybody with ten. `before` / `after` compare a date attribute as an absolute instant, unlike the rolling `within_days` window. `starts_with` / `ends_with` are not `contains`: an address AT acme.com and one mentioning acme.com anywhere are different audiences. A value these cannot parse \u2014 a non-numeric number, an unreadable date \u2014 matches NOTHING rather than everything, because a predicate we cannot evaluate must narrow the audience and never widen it."
                                                                    },
                                                                    "value": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Always present, unlike the stored rule, which omits the key entirely for operators that take no value. `null` for `is_set` / `is_not_set` \u2014 null rather than `\"\"`, which would read as \"equal to nothing\". A day count of 1\u2013365 for the engagement operators."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "contact_count": {
                                                            "type": "integer",
                                                            "description": "LIVE. A segment is a query, so this is what the rules match now, not what they matched when it was saved. Always an integer."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteSegmentsSegment",
                "summary": "Delete a segment",
                "tags": [
                    "Contacts"
                ],
                "x-required-scope": "contacts:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "segment",
                        "in": "path",
                        "required": true,
                        "description": "The segment identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. A segment is a saved query, so deleting it removes the definition and touches no contact."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/campaigns": {
            "get": {
                "operationId": "getCampaigns",
                "summary": "List campaigns",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "campaign"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Unique identifier for the campaign."
                                                                    },
                                                                    "name": {
                                                                        "type": "string"
                                                                    },
                                                                    "state": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "draft",
                                                                            "scheduled",
                                                                            "sending",
                                                                            "paused",
                                                                            "sent",
                                                                            "canceled",
                                                                            "unknown"
                                                                        ],
                                                                        "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                                    },
                                                                    "sender": {
                                                                        "type": "object",
                                                                        "nullable": true,
                                                                        "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                            },
                                                                            "email": {
                                                                                "type": "string",
                                                                                "format": "email"
                                                                            }
                                                                        }
                                                                    },
                                                                    "content": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "subject": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                            },
                                                                            "template_id": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                            },
                                                                            "has_html": {
                                                                                "type": "boolean",
                                                                                "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                            },
                                                                            "has_text": {
                                                                                "type": "boolean",
                                                                                "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                            },
                                                                            "html": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                            },
                                                                            "text": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                            }
                                                                        }
                                                                    },
                                                                    "audience": {
                                                                        "type": "object",
                                                                        "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                                        "properties": {
                                                                            "lists": {
                                                                                "type": "array",
                                                                                "nullable": true,
                                                                                "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                                "items": {
                                                                                    "type": "object",
                                                                                    "properties": {
                                                                                        "id": {
                                                                                            "type": "string"
                                                                                        },
                                                                                        "name": {
                                                                                            "type": "string"
                                                                                        },
                                                                                        "contact_count": {
                                                                                            "type": "integer",
                                                                                            "nullable": true,
                                                                                            "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                                        }
                                                                                    }
                                                                                }
                                                                            },
                                                                            "segments": {
                                                                                "type": "array",
                                                                                "nullable": true,
                                                                                "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                                "items": {
                                                                                    "type": "object",
                                                                                    "properties": {
                                                                                        "id": {
                                                                                            "type": "string"
                                                                                        },
                                                                                        "name": {
                                                                                            "type": "string"
                                                                                        }
                                                                                    }
                                                                                }
                                                                            },
                                                                            "excluded": {
                                                                                "type": "object",
                                                                                "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                                "properties": {
                                                                                    "count": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                                    },
                                                                                    "contact_ids": {
                                                                                        "type": "array",
                                                                                        "nullable": true,
                                                                                        "items": {
                                                                                            "type": "string"
                                                                                        },
                                                                                        "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    },
                                                                    "schedule": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "scheduled_for": {
                                                                                "type": "string",
                                                                                "format": "date-time",
                                                                                "nullable": true,
                                                                                "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                            },
                                                                            "started_at": {
                                                                                "type": "string",
                                                                                "format": "date-time",
                                                                                "nullable": true,
                                                                                "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                            },
                                                                            "completed_at": {
                                                                                "type": "string",
                                                                                "format": "date-time",
                                                                                "nullable": true,
                                                                                "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                            }
                                                                        }
                                                                    },
                                                                    "resent_from_campaign_id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                                    },
                                                                    "created_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    },
                                                                    "updated_at": {
                                                                        "type": "string",
                                                                        "format": "date-time"
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postCampaigns",
                "summary": "Create a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "A campaign is a bulk send to a list or segment, with unsubscribe handling, reporting\nand \u2014 for organizations new to marketing sending \u2014 a review step.\n\nCreating one does not send it. Schedule or send it explicitly, and call\n`preflight` first: it checks the things that get a campaign stopped, and it is far\ncheaper to fail there than halfway through a list."
            }
        },
        "/api/v1/campaigns/{campaign}": {
            "get": {
                "operationId": "getCampaignsCampaign",
                "summary": "Retrieve a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "operationId": "putCampaignsCampaign",
                "summary": "Update a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "operationId": "patchCampaignsCampaign",
                "summary": "Update a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteCampaignsCampaign",
                "summary": "Delete a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. Only a draft can be deleted \u2014 a paused campaign cannot, and resuming it is currently its only exit."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/campaigns/{campaign}/schedule": {
            "post": {
                "operationId": "postCampaignsCampaignSchedule",
                "summary": "Schedule a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/campaigns/{campaign}/send": {
            "post": {
                "operationId": "postCampaignsCampaignSend",
                "summary": "Send a campaign now",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Begins the send immediately.\n\nMarketing mail rides a different egress path from transactional mail, deliberately, so\na newsletter cannot damage the reputation that carries your password resets. New\nmarketing senders are rate-limited while they warm up, so a large first campaign will\ntake longer than you expect \u2014 that is the system working."
            }
        },
        "/api/v1/campaigns/{campaign}/pause": {
            "post": {
                "operationId": "postCampaignsCampaignPause",
                "summary": "Pause a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/campaigns/{campaign}/resume": {
            "post": {
                "operationId": "postCampaignsCampaignResume",
                "summary": "Resume a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/campaigns/{campaign}/cancel": {
            "post": {
                "operationId": "postCampaignsCampaignCancel",
                "summary": "Cancel a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/campaigns/{campaign}/resend": {
            "post": {
                "operationId": "postCampaignsCampaignResend",
                "summary": "Resend a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The field SET never varies between a list and a single campaign. Two values do: `content.html` / `content.text` and `audience.excluded_contact_ids` are null in a list response. See those fields.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the campaign."
                                                        },
                                                        "name": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The one lifecycle answer. `draft` is editable and going nowhere; `scheduled` is accepted and waiting for its send time; `sending` means the fan-out is running; `paused` means it stopped between chunks and is resumable; `sent` means the fan-out FINISHED, which is not the same as \"everyone received it\" \u2014 read `GET /campaigns/{campaign}/stats` for that, because a campaign can read `sent` with zero delivered; `canceled` means stopped for good, though it can still be resent. `unknown` means WE DID NOT RECOGNISE the stored status \u2014 it is not a reassurance and nothing is fine about it. It exists so a surprise is never published as a state implying a capability the campaign lacks: mapping it to `draft` would tell you the campaign is editable when it may be mid-send. Whether the campaign can actually go out is a separate question, answered only by `POST /campaigns/{campaign}/preflight` \u2014 in particular an organization awaiting marketing review is not a campaign state, because the campaign becomes sendable without being touched."
                                                        },
                                                        "sender": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The identity this sends as. `null` means the relation was not loaded, not that there is no sender \u2014 `sender_id` is NOT NULL. The sender's verification state is deliberately not repeated here; whether an unverified sender blocks THIS campaign is preflight's `sender_unverified`.",
                                                            "properties": {
                                                                "id": {
                                                                    "type": "string"
                                                                },
                                                                "name": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The sender's display name. In practice NEVER null: `senders.name` is NOT NULL, so a `sender` object that is present always carries one. The marker is defensive, not a case you have to handle \u2014 if the sender itself was not loaded the whole `sender` object is null, which is the field that says so."
                                                                },
                                                                "email": {
                                                                    "type": "string",
                                                                    "format": "email"
                                                                }
                                                            }
                                                        },
                                                        "content": {
                                                            "type": "object",
                                                            "properties": {
                                                                "subject": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The subject line. `null` means NONE \u2014 none has been written \u2014 never \"not included\": unlike `html` and `text` this is a real answer in a list response too. A draft normally starts this way; a campaign with no subject AND no template cannot be sent, and preflight reports that as `no_content`."
                                                                },
                                                                "template_id": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "A campaign either carries its own body or renders a template. The send path prefers the template when both are set. `null` means NONE \u2014 this campaign renders its own `subject` / `html` / `text` and no template is attached \u2014 never \"not included\": it is a real answer in a list response too."
                                                                },
                                                                "has_html": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `html !== null`."
                                                                },
                                                                "has_text": {
                                                                    "type": "boolean",
                                                                    "description": "ALWAYS a real answer, in a list as well as on a single campaign. This is the boolean to test \u2014 not `text !== null`."
                                                                },
                                                                "html": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The HTML body. `null` in a LIST response means NOT INCLUDED \u2014 we have not told you \u2014 and never \"empty\": a body has no size limit and a page of 25 campaigns would be megabytes nobody asked for. `has_html` is the field that says whether there is one. Fetch the campaign on its own to read it."
                                                                },
                                                                "text": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The plain-text body \u2014 stored as `plain_text`, published as `text`, which is the spelling the send payload uses. `null` in a LIST response means NOT INCLUDED, not empty; `has_text` is the real boolean. Fetch the campaign on its own to read it."
                                                                }
                                                            }
                                                        },
                                                        "audience": {
                                                            "type": "object",
                                                            "description": "Static lists plus rule-based segments, minus per-campaign exclusions \u2014 the union-then-subtract the send path materialises.",
                                                            "properties": {
                                                                "lists": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "The static lists this campaign sends to, named so you do not have to fetch each one to display it. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            },
                                                                            "contact_count": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "How many contacts are on the list. This is the list size, NOT a recipient total: lists and segments can overlap, exclusions are removed, and suppressed addresses are dropped at send. Null means the count was not read."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "segments": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Rule-based segments this campaign sends to. They carry no count: a segment has no fixed membership, its rules are evaluated against your contacts when the campaign sends, so any figure here would be a different number from the one that matters. Null only if the relation was not loaded.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "id": {
                                                                                "type": "string"
                                                                            },
                                                                            "name": {
                                                                                "type": "string"
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "excluded": {
                                                                    "type": "object",
                                                                    "description": "Contacts held back from this campaign only; their list membership is untouched.",
                                                                    "properties": {
                                                                        "count": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "How many contacts are excluded. Always present, including in a list response, so you can tell \"none excluded\" from \"not told you\" without fetching the campaign."
                                                                        },
                                                                        "contact_ids": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "items": {
                                                                                "type": "string"
                                                                            },
                                                                            "description": "`null` in a LIST response means NOT INCLUDED, never \"there are none\" \u2014 the set is unbounded, which is why `count` sits beside it. Fetch the campaign on its own to read the ids."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "schedule": {
                                                            "type": "object",
                                                            "properties": {
                                                                "scheduled_for": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "Non-null ONLY when `state` is `scheduled`. The stored column outlives the intention \u2014 a cancel leaves the old time in place, and `POST /campaigns` accepts one on a draft without scheduling anything \u2014 so this is read from the state instead, and the two can no longer disagree."
                                                                },
                                                                "started_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out began. Null until it does \u2014 and that is exactly the cut that makes every count in `/stats` and the whole timeline in `/report` null rather than zero."
                                                                },
                                                                "completed_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the fan-out finished \u2014 stamped by the last chunk, at the same moment `state` becomes `sent`. `null` means NONE: it has not finished. That covers a draft, a scheduled campaign, one still sending or paused, AND a canceled one, because cancel stops the fan-out rather than completing it. A resend clears it back to null along with the rest of the campaign's send record. Finishing the fan-out is not the same as everybody receiving it \u2014 read `GET /campaigns/{campaign}/stats` for that."
                                                                }
                                                            }
                                                        },
                                                        "resent_from_campaign_id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The campaign this one was resent from \u2014 the only way to tell a resend from an original. It is a campaign id you can fetch. `null` means NONE: this campaign is an original, not carved out of another one. Never \"we did not look\" \u2014 it is a column on the row already read, present in a list response as well as a single campaign."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/campaigns/{campaign}/test-send": {
            "post": {
                "operationId": "postCampaignsCampaignTestSend",
                "summary": "Send a test",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "A TEST SEND IS NOT A SEND. It goes through the per-message path, not the fan-out: the campaign's state, its recipient ledger and its stats are all untouched, and the subject is prefixed so nobody mistakes it for the real thing. It is also the one campaign action that does not re-assert the marketing-review gate \u2014 you can test a campaign you cannot yet send.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign_test_send"
                                                            ]
                                                        },
                                                        "campaign_id": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The campaign's lifecycle state, unchanged by the test send \u2014 identical before and after, which is the point of publishing it here."
                                                        },
                                                        "sent": {
                                                            "type": "integer",
                                                            "description": "Results with status `sent`. Derivable, and kept: it is the headline, and it is computed in the same pass as `results` so the two cannot disagree."
                                                        },
                                                        "requested": {
                                                            "type": "integer",
                                                            "description": "Addresses attempted \u2014 at most five."
                                                        },
                                                        "results": {
                                                            "type": "array",
                                                            "description": "One row per address, in the order given.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "email": {
                                                                        "type": "string",
                                                                        "format": "email",
                                                                        "nullable": true,
                                                                        "description": "The address this row is about. In practice NEVER null \u2014 a row exists only because an address was attempted, and the addresses are validated before any of this runs. The marker is defensive, not a case you have to handle."
                                                                    },
                                                                    "status": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "sent",
                                                                            "suppressed",
                                                                            "rate_limited",
                                                                            "failed",
                                                                            "unknown"
                                                                        ],
                                                                        "description": "`sent` was handed to the mail server; `suppressed` is on the organization's suppression list; `rate_limited` hit the organization's send rate limit; `failed` threw, see `error`. `unknown` means we did not recognise the value and should never be seen."
                                                                    },
                                                                    "error": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The raw exception message, PHP function names and all. Unstructured and not a closed set \u2014 do not parse it. Same wart as `campaign_recipient.error`, kept for the same reason. `null` means NONE \u2014 nothing went wrong on this row \u2014 and it is null exactly when `status` is `sent`: `suppressed` and `rate_limited` both carry a written explanation here rather than an exception, so a non-null `error` does not on its own mean the send threw."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Sends the campaign to addresses you name, so you can see it as a recipient would. Does not touch the audience and does not count against the campaign report."
            }
        },
        "/api/v1/campaigns/{campaign}/preflight": {
            "post": {
                "operationId": "postCampaignsCampaignPreflight",
                "summary": "Preflight a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "THE ONLY READINESS SURFACE in this section. A campaign does not carry its own blockers, because readiness depends on the organization's marketing-review state, the sender, the audience size and today's warm-up ceiling \u2014 none of them campaign columns, all of them moving without the campaign being touched. Preflighting a campaign that is not a draft is noise: it reports `not_draft` plus a full credit projection for a send that already happened.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign_preflight"
                                                            ]
                                                        },
                                                        "campaign_id": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The campaign's lifecycle state, from the same map `campaign.state` uses."
                                                        },
                                                        "sendable": {
                                                            "type": "boolean",
                                                            "description": "The verdict. Exactly `blockers === []`, computed in the same expression, and kept because \"is there anything in this array\" is a worse thing to have to write."
                                                        },
                                                        "blockers": {
                                                            "type": "array",
                                                            "description": "Everything that stops this campaign going out. Empty means sendable. Beware: `POST /send` and `POST /schedule` refuse with a validation error that carries the message but NOT the code, so preflight is the only place you get a stable code to branch on.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "code": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "not_draft",
                                                                            "marketing_review_pending",
                                                                            "sender_unverified",
                                                                            "no_content",
                                                                            "no_unsubscribe",
                                                                            "no_audience",
                                                                            "warmup_exceeded"
                                                                        ],
                                                                        "description": "Closed set. `not_draft`: only a draft can be scheduled. `marketing_review_pending`: the ORGANIZATION's marketing application is not approved \u2014 this is the gate that stops every new customer's first campaign, and it is not a campaign state because the campaign becomes sendable without being touched. `sender_unverified`: the campaign's sender is not verified. `no_content`: no subject plus HTML body, and no template. `no_unsubscribe`: the HTML carries no way to opt out. `no_audience`: no list and no segment targeted. `warmup_exceeded`: more recipients than today's warm-up ceiling leaves \u2014 advisory in one sense, since the real ceiling is enforced on the mail server and this stays silent rather than blocking every campaign when the inventory cannot be read."
                                                                    },
                                                                    "field": {
                                                                        "type": "string",
                                                                        "description": "Which part of the campaign the code is about."
                                                                    },
                                                                    "message": {
                                                                        "type": "string",
                                                                        "description": "Human-readable prose. Not stable \u2014 branch on `code`."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "warnings": {
                                                            "type": "array",
                                                            "description": "Worth knowing, does not stop the send.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "code": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "insufficient_credits"
                                                                        ],
                                                                        "description": "Closed set of one. `insufficient_credits`: the balance is below the recipient count. NOT a blocker, because scheduling does not refuse on an empty balance \u2014 calling it one would make preflight refuse something the API accepts."
                                                                    },
                                                                    "field": {
                                                                        "type": "string",
                                                                        "description": "Which part of the campaign the code is about."
                                                                    },
                                                                    "message": {
                                                                        "type": "string",
                                                                        "description": "Human-readable prose. Not stable \u2014 branch on `code`."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "recipient_count": {
                                                            "type": "integer",
                                                            "description": "The projected distinct sendable set, by the same rule the send path materialises, so the answer is stable whether or not the recipient rows exist yet. Always an integer \u2014 unlike the stats counts, this is a projection that can always be made."
                                                        },
                                                        "credit_balance": {
                                                            "type": "integer",
                                                            "description": "Whole sends, not money: one credit is one recipient. The organization's balance in currency belongs to billing."
                                                        },
                                                        "personalization": {
                                                            "type": "object",
                                                            "properties": {
                                                                "variables": {
                                                                    "type": "array",
                                                                    "description": "Which template variables the content uses. Called `variables`, not `tags`, because this API already uses `tags` for the send-time correlation labels stamped on every message.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "name": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The variable, without braces. In practice NEVER null \u2014 a row exists here only because the scanner matched a named `{{ tag }}` in the content, so there is always a name to publish. The marker is defensive against a malformed scanner row, not a case you have to handle."
                                                                            },
                                                                            "system": {
                                                                                "type": "boolean",
                                                                                "description": "True for variables always available at send time: `email`, `sender_name`, `sender_email`, `organization_name`, `unsubscribe_url`. A system variable's `missing` is always 0. `name` is NOT one of them \u2014 it comes off the contact row and a contact may have none, so it is counted like any other contact-backed variable."
                                                                            },
                                                                            "missing": {
                                                                                "type": "integer",
                                                                                "description": "Recipients in the audience with no value for it. A count, not a rate \u2014 `recipient_count` is the denominator if you want one."
                                                                            },
                                                                            "default": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The organization's contact-field default, which fills a blank at send time. A variable with a default is never actually empty, so a non-zero `missing` beside a non-null `default` is informational rather than a problem."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "has_unsubscribe": {
                                                                    "type": "boolean",
                                                                    "description": "Whether the content satisfies the compliance gate that `no_unsubscribe` enforces. The blocker is the refusal; this is the observation, and both read the same check."
                                                                }
                                                            }
                                                        },
                                                        "warmup": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Today's warm-up ceiling for the sending address. `null` has TWO meanings here and they are not the same thing. Usually it is NONE \u2014 the question does not apply, because the organization is not warming a dedicated IP, which is almost all of them, or its address has no ceiling set yet; a zeroed object would read as \"no headroom\". But it is also null when the IP inventory COULD NOT BE READ \u2014 the mail server was unreachable \u2014 and this response cannot tell you which happened. That is deliberate on the blocking side: `warmup_exceeded` stays silent rather than refusing every campaign because an inventory read failed, and the real ceiling is enforced on the mail server regardless. It is a genuine gap on the reporting side, recorded in plans/13-public-api-contract/converted/campaigns.md. When the object IS present, every member of it is a real number.",
                                                            "properties": {
                                                                "day": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Which day of the warm-up curve this is. Never null when the enclosing `warmup` object is present \u2014 the snapshot that builds it either has every figure or is itself null."
                                                                },
                                                                "ceiling": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Today's allowance, in recipients. Never null when the enclosing `warmup` object is present: an address whose ceiling has not been set is one the warm-up engine has not started pacing, and that case makes `warmup` itself null rather than reporting a ceiling of zero."
                                                                },
                                                                "sent_today": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients already sent on this address today, counted from our own delivery rollup. Never null when the enclosing `warmup` object is present, and **`0` means NOTHING SENT YET, not \"we could not read the meter\"** \u2014 the unreadable case makes the whole `warmup` object null, it never surfaces as a zero here. That distinction is the difference between a client believing it has a full day's headroom and knowing it has no figure at all."
                                                                },
                                                                "remaining": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "`ceiling - sent_today`, floored at 0. Kept although it is derived: it is what `warmup_exceeded` compares against, and publishing the comparison the gate actually makes is worth one derived integer. Never null when the enclosing `warmup` object is present."
                                                                },
                                                                "recipients": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "What THIS campaign would add \u2014 the same projection as the top-level `recipient_count`. Never null when the enclosing `warmup` object is present."
                                                                },
                                                                "completes_on": {
                                                                    "type": "string",
                                                                    "format": "date",
                                                                    "nullable": true,
                                                                    "description": "The date the curve finishes. This is the ONE member of `warmup` that really can be null while the object is present, and it means UNKNOWN: the inventory row carries no readable warm-up start date, so there is nothing to add the configured warm-up length to. It does NOT mean the curve never finishes."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Checks a campaign for the problems that would stop it \u2014 unverified domain, missing unsubscribe, empty audience, insufficient allowance \u2014 without sending anything."
            }
        },
        "/api/v1/campaigns/{campaign}/report": {
            "get": {
                "operationId": "getCampaignsCampaignReport",
                "summary": "Report a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign_report"
                                                            ]
                                                        },
                                                        "campaign_id": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The campaign's lifecycle state, from the same map `campaign.state` uses."
                                                        },
                                                        "timeline": {
                                                            "type": "object",
                                                            "description": "Engagement per bucket from the send start to the last observed event. BOTH members are null for a campaign that never started \u2014 an empty `points` array beside a confident bucket size would read as \"we measured and nothing happened\", which is a different fact from \"there is no window to measure over\". Same cut as the stats counts, from the same column.",
                                                            "properties": {
                                                                "bucket": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "hour",
                                                                        "day"
                                                                    ],
                                                                    "nullable": true,
                                                                    "description": "`hour` while the window is short enough to read that way (72 hours), `day` after. Null when there is no window."
                                                                },
                                                                "points": {
                                                                    "type": "array",
                                                                    "nullable": true,
                                                                    "description": "Null when the campaign never started; never `[]` in that case.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "at": {
                                                                                "type": "string",
                                                                                "format": "date-time",
                                                                                "nullable": true,
                                                                                "description": "The bucket boundary as an INSTANT, ISO 8601 UTC. The underlying value is a bucket label with no timezone and no `T`; publishing it unchanged meant every date parser read it as local time. `null` means UNKNOWN \u2014 the stored bucket label was empty or did not parse against this row's `bucket` format, so we could not say which instant it is. It never means \"no time\": the row's counts are still real, they just cannot be placed on the axis. Drop such a point rather than guessing where it goes."
                                                                            },
                                                                            "delivered": {
                                                                                "type": "integer"
                                                                            },
                                                                            "opened": {
                                                                                "type": "integer"
                                                                            },
                                                                            "clicked": {
                                                                                "type": "integer"
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "links": {
                                                            "type": "array",
                                                            "description": "Clicks grouped by DESTINATION, most-clicked first \u2014 a per-destination table, not a list of click events. At most 50 rows; no campaign at today's volumes comes near that. No ratio is published: you have both inputs.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "url": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Can be the literal string `(unknown link)`: click events from before the tracking pipeline echoed the original URL are grouped under it rather than dropped, so `total_clicks` still sums to `engagement.clicked`. It is a display sentinel in a data field and a known wart."
                                                                    },
                                                                    "total_clicks": {
                                                                        "type": "integer",
                                                                        "description": "Every click on this destination."
                                                                    },
                                                                    "unique_clickers": {
                                                                        "type": "integer",
                                                                        "description": "Distinct recipients who clicked it. Five clicks from one person is not five interested readers, which is why both numbers are kept."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/campaigns/{campaign}/stats": {
            "get": {
                "operationId": "getCampaignsCampaignStats",
                "summary": "Stats a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "No rates are published: you have both inputs, and a published percentage bakes in a denominator and a rounding rule we could never change. CORRELATION CAVEAT: only events tagged `campaign:{id}` are exact. Opens, clicks, bounces and unsubscribes arrive from the tracking pipeline without that tag and are matched by recipient address within the campaign's active window, so an address on two overlapping campaigns can have one open counted against both. Counts are unique by recipient.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "campaign_stats"
                                                            ]
                                                        },
                                                        "campaign_id": {
                                                            "type": "string"
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "draft",
                                                                "scheduled",
                                                                "sending",
                                                                "paused",
                                                                "sent",
                                                                "canceled",
                                                                "unknown"
                                                            ],
                                                            "description": "The campaign's lifecycle state, repeated from the same map `campaign.state` uses so the numbers can be read without a second request. Note that `sent` describes the fan-out finishing, not the numbers below: a campaign can read `sent` with `recipients.sent: 0`."
                                                        },
                                                        "recipients": {
                                                            "type": "object",
                                                            "description": "What the fan-out did with the ledger. EVERY count in this group is `null` until the campaign starts, and an integer from the moment it does. The cut is exact, not a guess: the recipient ledger is materialised and the measurement window opens in the same save that sets `schedule.started_at`, so `started_at === null` is precisely \"no ledger, no window, nothing measured\". Null here means UNKNOWN, never zero \u2014 \"nobody opened it\" and \"it has not been sent\" are different facts.",
                                                            "properties": {
                                                                "total": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Every row in the recipient ledger. Null until the campaign starts \u2014 see the group description."
                                                                },
                                                                "pending": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Materialised, not yet attempted. Null until the campaign starts \u2014 see the group description."
                                                                },
                                                                "sent": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Handed to the mail server. NOT a delivery confirmation \u2014 that is `engagement.delivered`, and the two are kept separate because a campaign with `sent` above `delivered` has mail in flight or bounced. Null until the campaign starts \u2014 see the group description."
                                                                },
                                                                "failed": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "The send attempt threw. Null until the campaign starts \u2014 see the group description."
                                                                },
                                                                "skipped_suppressed": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "On the organization's suppression list. Null until the campaign starts \u2014 see the group description."
                                                                },
                                                                "skipped_unsubscribed": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Opted out of this organization's mail. Null until the campaign starts \u2014 see the group description."
                                                                }
                                                            }
                                                        },
                                                        "engagement": {
                                                            "type": "object",
                                                            "description": "What came back. EVERY count in this group is `null` until the campaign starts, and an integer from the moment it does. The cut is exact, not a guess: the recipient ledger is materialised and the measurement window opens in the same save that sets `schedule.started_at`, so `started_at === null` is precisely \"no ledger, no window, nothing measured\". Null here means UNKNOWN, never zero \u2014 \"nobody opened it\" and \"it has not been sent\" are different facts.",
                                                            "properties": {
                                                                "delivered": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Confirmations received from the receiving server. Null until the campaign starts \u2014 see the group description."
                                                                },
                                                                "opened": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Unique recipients who opened. Null until the campaign starts \u2014 see the group description."
                                                                },
                                                                "clicked": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Unique recipients who clicked. Null until the campaign starts \u2014 see the group description."
                                                                },
                                                                "bounced": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Unique recipients whose message bounced. Null until the campaign starts \u2014 see the group description."
                                                                },
                                                                "unsubscribed": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Unique recipients who opted out from this message. Null until the campaign starts \u2014 see the group description."
                                                                }
                                                            }
                                                        },
                                                        "generated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When this rollup was computed. The endpoint recomputes on every call rather than reading the campaign's cached copy, so it is always \"just now\" \u2014 published anyway, because a caller storing the answer needs to know how old their copy is. In practice NEVER null: the service stamps it on every rollup it returns. The marker is defensive, and a null would mean UNKNOWN \u2014 the rollup reached us without a timestamp \u2014 never \"it has not been computed\", because the counts beside it would not exist if it had not been."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/campaigns/{campaign}/recipients": {
            "get": {
                "operationId": "getCampaignsCampaignRecipients",
                "summary": "Recipients a campaign",
                "tags": [
                    "Campaigns"
                ],
                "x-required-scope": "campaigns:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "campaign",
                        "in": "path",
                        "required": true,
                        "description": "The campaign identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "campaign_recipient"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "Unique identifier for the recipient row."
                                                                    },
                                                                    "email": {
                                                                        "type": "string",
                                                                        "format": "email"
                                                                    },
                                                                    "contact_id": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Null for an address that reached the campaign without a contact row behind it."
                                                                    },
                                                                    "status": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "pending",
                                                                            "sent",
                                                                            "failed",
                                                                            "skipped_suppressed",
                                                                            "skipped_unsubscribed",
                                                                            "unknown"
                                                                        ],
                                                                        "description": "`pending` is materialised but not yet attempted; `sent` was handed to the mail server; `failed` threw, see `error`; `skipped_suppressed` is on the organization's suppression list; `skipped_unsubscribed` opted out. `unknown` means we did not recognise the stored value and should never be seen."
                                                                    },
                                                                    "error": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The failure reason, VERBATIM from the send attempt \u2014 today that is whatever the transport threw, PHP function names included. Do not parse it or branch on it: it is unstructured, it is not a closed set, and it will change. It is published because `status: \"failed\"` on its own leaves you unable to tell a bad address from a broken TLS handshake. `null` means NONE \u2014 nothing went wrong on this row \u2014 and it is cleared back to null when a resend resets the recipient to `pending`. It is never \"we did not look\": `status` is the field that tells you whether to expect one."
                                                                    },
                                                                    "sent_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When the message was submitted to the mail server. NOT a delivery confirmation \u2014 that is `engagement.delivered` on the campaign's stats. Stamped only on `status: \"sent\"`, so `null` means NONE \u2014 nothing was submitted for this row \u2014 which covers `pending`, `failed` and both `skipped_*` statuses. It is never \"we did not look\". One wrinkle: a resend resets the row to `pending` and clears `error` but LEAVES this timestamp, so a `pending` row on a resent campaign can carry the previous attempt's time. Read `status` first."
                                                                    },
                                                                    "opened_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "FIRST correlated open \u2014 a recipient who opens five times has one `opened_at`. Not a stored column: it is correlated from the delivery-event ledger and exists only on this endpoint. Null means none was observed, which for a campaign that has not started means nothing has been measured at all."
                                                                    },
                                                                    "clicked_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "First correlated click, on the same terms as `opened_at`: not a stored column, correlated from the delivery-event ledger, and available only on this endpoint. `null` means NONE was observed \u2014 no click has been correlated to this recipient \u2014 which for a campaign that has not started means nothing has been measured at all. It is correlated from `tracking.click` events, so it also reads null for a message whose links the tracking pipeline never produced an event for."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/deliverability": {
            "get": {
                "operationId": "getDeliverability",
                "summary": "List deliverabilitys",
                "tags": [
                    "Reports"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "deliverability_report"
                                                            ]
                                                        },
                                                        "score": {
                                                            "type": "integer",
                                                            "description": "0-100."
                                                        },
                                                        "band": {
                                                            "type": "string",
                                                            "enum": [
                                                                "needs_attention",
                                                                "good",
                                                                "excellent"
                                                            ],
                                                            "description": "`score` bucketed. A VALUE, not a display label: this used to be `\"Needs attention\"`, Title Case with a space, which no caller could switch on without matching English."
                                                        },
                                                        "window_days": {
                                                            "type": "integer",
                                                            "description": "Everything in this report is computed over this many days, ending now."
                                                        },
                                                        "volume": {
                                                            "type": "object",
                                                            "description": "Counts -- things that happened. Split from `rates` because the two used to sit flat in one `metrics` bag, told apart only by an `_rate` suffix, so `bounced: 1` read as a contradiction beside `bounce_rate: 50`.",
                                                            "properties": {
                                                                "submitted": {
                                                                    "type": "integer",
                                                                    "description": "DISTINCT message ids across outbound mail events, not `email.submitted` events -- nothing emits those on the ingest path, so counting them showed 0 forever beside non-zero rates."
                                                                },
                                                                "delivered": {
                                                                    "type": "integer"
                                                                },
                                                                "bounced": {
                                                                    "type": "integer"
                                                                },
                                                                "opened": {
                                                                    "type": "integer"
                                                                },
                                                                "clicked": {
                                                                    "type": "integer"
                                                                },
                                                                "complaints": {
                                                                    "type": "integer",
                                                                    "description": "`delivery.complaint` events."
                                                                },
                                                                "unsubscribed": {
                                                                    "type": "integer"
                                                                }
                                                            }
                                                        },
                                                        "rates": {
                                                            "type": "object",
                                                            "description": "PERCENTAGES, 0-100, not fractions: a bounce rate of 50 is half. The `_rate` suffix is redundant under this key and is gone. They divide by `max(volume.delivered, volume.submitted, 1)`, so a rate can exceed what a naive reading of `volume` suggests when tracking events outnumber known messages.",
                                                            "properties": {
                                                                "open": {
                                                                    "type": "number"
                                                                },
                                                                "click": {
                                                                    "type": "number"
                                                                },
                                                                "bounce": {
                                                                    "type": "number"
                                                                },
                                                                "negative_engagement": {
                                                                    "type": "number",
                                                                    "description": "Complaints and unsubscribes together."
                                                                }
                                                            }
                                                        },
                                                        "authentication": {
                                                            "type": "object",
                                                            "description": "Per-domain SPF/DKIM/DMARC. HIDDEN DOMAINS ARE EXCLUDED here, as on the Domains page -- but they still send, so `volume` above DOES count their mail. The two sets differ deliberately, which is why this block names the domains it scored instead of only publishing an average.",
                                                            "properties": {
                                                                "average_score": {
                                                                    "type": "number",
                                                                    "description": "0-100."
                                                                },
                                                                "domains": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "domain": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "The domain name these three flags are about. NULL WOULD MEAN UNKNOWN and cannot happen: each row is one of your domain records and the column is NOT NULL. An unauthenticated domain still appears here NAMED, with `spf`/`dkim`/`dmarc` false and `score` 0 -- a domain is never anonymised into a null row, because the whole reason this list is published beside `average_score` is to say which domains dragged it down."
                                                                            },
                                                                            "score": {
                                                                                "type": "integer",
                                                                                "description": "0-100."
                                                                            },
                                                                            "spf": {
                                                                                "type": "boolean"
                                                                            },
                                                                            "dkim": {
                                                                                "type": "boolean"
                                                                            },
                                                                            "dmarc": {
                                                                                "type": "boolean"
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "recommendations": {
                                                            "type": "array",
                                                            "description": "What to fix, worst first. Empty when there is nothing to say.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "severity": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "critical",
                                                                            "warning",
                                                                            "info"
                                                                        ]
                                                                    },
                                                                    "message": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Human-readable prose. Not a stable identifier -- do not match on it; the wording carries live figures and domain names and is rewritten whenever the advice changes. NULL WOULD MEAN UNKNOWN and cannot happen: every recommendation this report can emit is built with its sentence, so a row without one is not a recommendation with nothing to say. If you need to branch, branch on `severity`, which IS a closed set."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/reports/email-delivery": {
            "get": {
                "operationId": "getReportsEmailDelivery",
                "summary": "Email Delivery (report)",
                "tags": [
                    "Reports"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "email_delivery_report"
                                                            ]
                                                        },
                                                        "generated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                        },
                                                        "period": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.",
                                                            "properties": {
                                                                "start_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "end_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "granularity": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "day"
                                                                    ],
                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                }
                                                            }
                                                        },
                                                        "totals": {
                                                            "type": "object",
                                                            "description": "The counts for the whole period. No rates: every rate this endpoint used to publish was arithmetic over counts sitting beside it, and two fields that can disagree -- which rounding guarantees -- are a bug report waiting to be filed. The counts are published; divide them yourself.",
                                                            "properties": {
                                                                "sent": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Every delivery event recorded in the window: delivered, bounced, deferred, rejected and dropped. It is NOT `delivered + bounced + failed` -- deferrals are counted in and are broken out nowhere in the response, so `sent` is normally larger than the three figures beside it. Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "delivered": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "bounced": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages a receiving server refused (`email.bounced`). Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "failed": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Permanent non-delivery: rejected plus dropped. A deferral is a retry, not a failure, and is not counted here. Null means the figure is unavailable, never that it is zero."
                                                                }
                                                            }
                                                        },
                                                        "series": {
                                                            "type": "array",
                                                            "description": "The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "start_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live."
                                                                    },
                                                                    "sent": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Every delivery event recorded in the window: delivered, bounced, deferred, rejected and dropped. It is NOT `delivered + bounced + failed` -- deferrals are counted in and are broken out nowhere in the response, so `sent` is normally larger than the three figures beside it. Null means the figure is unavailable, never that it is zero."
                                                                    },
                                                                    "delivered": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                    },
                                                                    "bounced": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Messages a receiving server refused (`email.bounced`). Null means the figure is unavailable, never that it is zero."
                                                                    },
                                                                    "failed": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Permanent non-delivery: rejected plus dropped. A deferral is a retry, not a failure, and is not counted here. Null means the figure is unavailable, never that it is zero."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "bounce_reasons": {
                                                            "type": "array",
                                                            "description": "The ten most frequent bounce reasons in the window, most frequent first. There is no `percentage` on a row: it was `count / bounced`, and both numbers are already in this response.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "reason": {
                                                                        "type": "string",
                                                                        "description": "The reason as the bounce event reported it. `unknown` is a real value here, not a null: it groups bounces whose payload carried no `bounce_reason`, and dropping them would make these counts fail to add up to `totals.bounced`."
                                                                    },
                                                                    "count": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Bounces in the window with this reason. Null means the figure is unavailable, never that it is zero."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/reports/engagement": {
            "get": {
                "operationId": "getReportsEngagement",
                "summary": "Engagement (report)",
                "tags": [
                    "Reports"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "engagement_report"
                                                            ]
                                                        },
                                                        "generated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                        },
                                                        "period": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.",
                                                            "properties": {
                                                                "start_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "end_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "granularity": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "day"
                                                                    ],
                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                }
                                                            }
                                                        },
                                                        "totals": {
                                                            "type": "object",
                                                            "description": "Engagement measured against DELIVERED mail. `delivered` is the denominator -- an open rate over messages that bounced is meaningless -- and it is the same number, under the same name, that `/reports/email-delivery` publishes. No `open_rate`, `click_rate` or `unsubscribe_rate`: divide by `delivered`.",
                                                            "properties": {
                                                                "delivered": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "opened": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Open events (`tracking.open`). Events, not people: one recipient opening twice counts twice. Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "clicked": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Click events (`tracking.click`). Events, not people. Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "unsubscribed": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Unsubscribe events (`tracking.unsubscribe`). Null means the figure is unavailable, never that it is zero."
                                                                }
                                                            }
                                                        },
                                                        "series": {
                                                            "type": "array",
                                                            "description": "The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "start_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live."
                                                                    },
                                                                    "delivered": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                    },
                                                                    "opened": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Open events (`tracking.open`). Events, not people: one recipient opening twice counts twice. Null means the figure is unavailable, never that it is zero."
                                                                    },
                                                                    "clicked": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Click events (`tracking.click`). Events, not people. Null means the figure is unavailable, never that it is zero."
                                                                    },
                                                                    "unsubscribed": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Unsubscribe events (`tracking.unsubscribe`). Null means the figure is unavailable, never that it is zero."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/reports/domain-health": {
            "get": {
                "operationId": "getReportsDomainHealth",
                "summary": "Domain Health (report)",
                "tags": [
                    "Reports"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "domain_health_report"
                                                            ]
                                                        },
                                                        "generated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                        },
                                                        "period": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Always null. This report is a snapshot of current DNS state, not a windowed aggregate: `ReportService::domainHealth()` takes no date range and the `date_range` query parameter is ignored.",
                                                            "properties": {
                                                                "start_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "end_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "granularity": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "day"
                                                                    ],
                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                }
                                                            }
                                                        },
                                                        "domains": {
                                                            "type": "array",
                                                            "description": "One row per domain in your organization, soft-deleted domains excluded.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "domain_health"
                                                                        ]
                                                                    },
                                                                    "domain": {
                                                                        "type": "string",
                                                                        "description": "The domain name. NOT NULLABLE, and that is a claim rather than an oversight: `domains.domain` is `varchar(255) NOT NULL UNIQUE` and the only producer reads it straight off the model, so there is no path that yields a row without one. Publishing it as nullable would have made every caller write a null check for a case that cannot occur, which is its own wrong promise. Pinned by PublicReportContractTest::test_a_domain_health_row_never_publishes_a_null_domain."
                                                                    },
                                                                    "dns": {
                                                                        "type": "object",
                                                                        "description": "The one lifecycle answer for this domain's DNS. The row used to carry the domains table's own `status` (\"Active\"/\"Inactive\") beside `dns_status`, which could disagree with it.",
                                                                        "properties": {
                                                                            "state": {
                                                                                "type": "string",
                                                                                "enum": [
                                                                                    "verified",
                                                                                    "pending",
                                                                                    "failed",
                                                                                    "unknown"
                                                                                ],
                                                                                "description": "Normalised and closed. The underlying column is free text and holds both `failed` and `Failed`, plus NULL for most rows; anything outside the three known values is `unknown`, which is why the buckets in `totals` always sum."
                                                                            },
                                                                            "verified": {
                                                                                "type": "boolean",
                                                                                "description": "True only for `verified`. `pending` and `failed` are both \"not verified\" to a caller deciding whether to send."
                                                                            }
                                                                        }
                                                                    },
                                                                    "spam_score": {
                                                                        "type": "number",
                                                                        "nullable": true,
                                                                        "description": "Always null today: nothing in this stack computes a spam score. Null rather than 0 because 0 would read as the worst possible verdict rather than as a gap. Kept in the shape because reputation IS domain health -- this report exists to answer it."
                                                                    },
                                                                    "reputation_score": {
                                                                        "type": "number",
                                                                        "nullable": true,
                                                                        "description": "Always null today, for the same reason as `spam_score`."
                                                                    },
                                                                    "checked_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "Sourced from the domain record's `updated_at`, so it moves whenever anything about the domain changes and is not necessarily when DNS was last checked. Treat it as \"as of\", not as a check timestamp."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "totals": {
                                                            "type": "object",
                                                            "description": "DNS-state bucket counts, recounted from the rows above rather than copied from the service. `verified + pending + failed + unknown` always equals `domains`. NOTE these count domains, not messages: `failed` here is a DNS state, unrelated to the delivery report's `failed`.",
                                                            "properties": {
                                                                "domains": {
                                                                    "type": "integer",
                                                                    "description": "Rows in `domains`."
                                                                },
                                                                "verified": {
                                                                    "type": "integer",
                                                                    "description": "Domains whose DNS has passed."
                                                                },
                                                                "pending": {
                                                                    "type": "integer",
                                                                    "description": "Domains whose DNS check has not finished."
                                                                },
                                                                "failed": {
                                                                    "type": "integer",
                                                                    "description": "Domains whose DNS check failed."
                                                                },
                                                                "unknown": {
                                                                    "type": "integer",
                                                                    "description": "Domains whose `dns_config_status` is NULL or a value outside the closed set. Most domains sit here. Before the buckets were recounted, these were counted into nothing and the three buckets silently failed to add up to the number of domains."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/reports/volume-trends": {
            "get": {
                "operationId": "getReportsVolumeTrends",
                "summary": "Volume Trends (report)",
                "tags": [
                    "Reports"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "volume_report"
                                                            ]
                                                        },
                                                        "generated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                        },
                                                        "period": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.",
                                                            "properties": {
                                                                "start_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "end_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "granularity": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "day"
                                                                    ],
                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                }
                                                            }
                                                        },
                                                        "totals": {
                                                            "type": "object",
                                                            "description": "The top-line counts. `average_daily_volume` and `peak_volume` are gone: both were one line of caller code over `series`, and both were computed from `events`, which is not a message count.",
                                                            "properties": {
                                                                "events": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "sent": {
                                                                    "type": "integer",
                                                                    "nullable": false,
                                                                    "description": "In THIS report only, `sent` is `delivered + bounced` -- the messages that reached a receiving server and got a verdict. `/reports/email-delivery` publishes `sent` as five event types (deferrals, rejections and drops as well), so the same name returns a different and smaller number here. Do not compare the two directly. Recorded as a defect in plans/13-public-api-contract/converted/mailserver.md; the counts are published as the service computes them rather than quietly reconciled. Summed from `series`, so the two can never drift apart."
                                                                },
                                                                "received": {
                                                                    "type": "integer",
                                                                    "nullable": false,
                                                                    "description": "Inbound mail (`email.inbound`). Summed from `series`."
                                                                }
                                                            }
                                                        },
                                                        "series": {
                                                            "type": "array",
                                                            "description": "The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "start_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live."
                                                                    },
                                                                    "events": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                    },
                                                                    "sent": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "In THIS report only, `sent` is `delivered + bounced` -- the messages that reached a receiving server and got a verdict. `/reports/email-delivery` publishes `sent` as five event types (deferrals, rejections and drops as well), so the same name returns a different and smaller number here. Do not compare the two directly. Recorded as a defect in plans/13-public-api-contract/converted/mailserver.md; the counts are published as the service computes them rather than quietly reconciled. Null means the figure is unavailable, never that it is zero."
                                                                    },
                                                                    "received": {
                                                                        "type": "integer",
                                                                        "nullable": true,
                                                                        "description": "Inbound mail (`email.inbound`). Null means the figure is unavailable, never that it is zero."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "distributions": {
                                                            "type": "object",
                                                            "description": "Histograms, not time series, which is why they are not `series`. TWO CAVEATS, both unchanged behaviour: the buckets are SPARSE -- an hour or a weekday with no events has no row rather than a zero -- and they are cut on the SERVER's application timezone, not yours and not UTC, so a bucket label is only meaningful once you know that timezone. The `percentage` each row used to carry is gone; it duplicated `events` over `totals.events`.",
                                                            "properties": {
                                                                "hour_of_day": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "bucket": {
                                                                                "type": "string",
                                                                                "description": "`\"00\"` to `\"23\"`."
                                                                            },
                                                                            "events": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                "day_of_week": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "bucket": {
                                                                                "type": "string",
                                                                                "description": "`\"Monday\"` to `\"Sunday\"`, in English."
                                                                            },
                                                                            "events": {
                                                                                "type": "integer",
                                                                                "nullable": true,
                                                                                "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/reports/security": {
            "get": {
                "operationId": "getReportsSecurity",
                "summary": "Security (report)",
                "tags": [
                    "Reports"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "security_report"
                                                            ]
                                                        },
                                                        "generated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                        },
                                                        "period": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "Null while `availability.state` is `unavailable`, which is every response today: there is no window because nothing was measured over one.",
                                                            "properties": {
                                                                "start_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "end_at": {
                                                                    "type": "string",
                                                                    "format": "date-time"
                                                                },
                                                                "granularity": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "day"
                                                                    ],
                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                }
                                                            }
                                                        },
                                                        "availability": {
                                                            "type": "object",
                                                            "description": "Whether there is a detection engine behind these figures. Check this BEFORE reading `totals` -- the counts are null, not zero, while it says `unavailable`.",
                                                            "properties": {
                                                                "state": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "available",
                                                                        "unavailable"
                                                                    ],
                                                                    "description": "Today always `unavailable`. No spam, malware or phishing detection data source exists yet in mailyte-api or the mail server."
                                                                },
                                                                "reason": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "Why the figures are unavailable. Null when they are not."
                                                                }
                                                            }
                                                        },
                                                        "totals": {
                                                            "type": "object",
                                                            "description": "ALL NULL today, and that is the point. This endpoint used to answer `available: false` and then report zero spam, zero malware and zero phishing -- which is not \"no data\", it is a clean bill of health. A customer charting it saw a flat green line and a customer alerting on it never alerted. Null says \"we have not measured\"; treat it as unknown, never as none.",
                                                            "properties": {
                                                                "scanned": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages put through spam, malware and phishing detection. Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "spam": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages detection classified as spam. Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "malware": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages detection found malware in. Null means the figure is unavailable, never that it is zero."
                                                                },
                                                                "phishing": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Messages detection classified as phishing. Null means the figure is unavailable, never that it is zero."
                                                                }
                                                            }
                                                        },
                                                        "series": {
                                                            "type": "array",
                                                            "nullable": true,
                                                            "description": "Null while `availability.state` is `unavailable`, which is always. Nothing produces security trend rows, so publishing `[]` would assert there were no incidents. When a detection engine exists these rows will carry the section's standard `start_at` plus the counts above; only `availability.state` and the nulls change.",
                                                            "items": {
                                                                "type": "object"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/reports/history": {
            "get": {
                "operationId": "getReportsHistory",
                "summary": "History (report)",
                "tags": [
                    "Reports"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "data": {
                                                            "type": "array",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "object": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "report_generation"
                                                                        ]
                                                                    },
                                                                    "id": {
                                                                        "type": "string",
                                                                        "description": "ULID. `POST /reports/generate` used to call this `report_id` and `GET /reports/history` called it `id`, so following a report you had just queued meant knowing the two were the same field. One name now, and a generate response IS a history row."
                                                                    },
                                                                    "template_id": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "email-delivery",
                                                                            "domain-health",
                                                                            "engagement",
                                                                            "volume-trends",
                                                                            "security"
                                                                        ],
                                                                        "description": "Matches the `id` of a row from `GET /reports/templates`. Note `security` is accepted here but is not advertised by that endpoint."
                                                                    },
                                                                    "format": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "pdf",
                                                                            "csv",
                                                                            "json"
                                                                        ],
                                                                        "description": "The format you asked for. The job stores a JSON snapshot whichever you ask for -- PDF and CSV rendering is not built -- so this records the request, not what `result` is."
                                                                    },
                                                                    "status": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "pending",
                                                                            "processing",
                                                                            "completed",
                                                                            "failed"
                                                                        ],
                                                                        "description": "Poll this. There is deliberately no `estimated_completion`: it was `now() + 30 seconds`, hardcoded and unrelated to the queue depth, the job or the report's size, so polling against it polled at the wrong time."
                                                                    },
                                                                    "parameters": {
                                                                        "type": "object",
                                                                        "additionalProperties": true,
                                                                        "description": "What the report was queued with. Always an object: it is an array cast, so it used to serialise as `[]` when empty and `{}` otherwise, and a field whose JSON type changes with its contents is unusable from a typed language."
                                                                    },
                                                                    "error": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "Why the build failed. Non-null only when `status` is `failed`. NULL MEANS NONE -- there is no error -- not that we lost the reason: the only two writers (`GenerateReportJob::handle()` and its `failed()` hook) set `status` and `error` in the same update, so a `failed` row always carries one and no other status ever does."
                                                                    },
                                                                    "result": {
                                                                        "nullable": true,
                                                                        "description": "The stored report, rendered through the SAME resource the live endpoint uses, so the vocabulary is identical whether you read a report live or out of history. Returning the raw snapshot would have re-published `total_volume`, `bounce_rate`, `total_sent` and the rest through the back door. Null while the job is queued, when it failed, and for a template we have no resource for. Its `period` is always null -- a snapshot keeps no record of the window it covered.",
                                                                        "oneOf": [
                                                                            {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "object": {
                                                                                        "type": "string",
                                                                                        "enum": [
                                                                                            "email_delivery_report"
                                                                                        ]
                                                                                    },
                                                                                    "generated_at": {
                                                                                        "type": "string",
                                                                                        "format": "date-time",
                                                                                        "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                                    },
                                                                                    "period": {
                                                                                        "type": "object",
                                                                                        "nullable": true,
                                                                                        "description": "The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.",
                                                                                        "properties": {
                                                                                            "start_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "end_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "granularity": {
                                                                                                "type": "string",
                                                                                                "enum": [
                                                                                                    "day"
                                                                                                ],
                                                                                                "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "totals": {
                                                                                        "type": "object",
                                                                                        "description": "The counts for the whole period. No rates: every rate this endpoint used to publish was arithmetic over counts sitting beside it, and two fields that can disagree -- which rounding guarantees -- are a bug report waiting to be filed. The counts are published; divide them yourself.",
                                                                                        "properties": {
                                                                                            "sent": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Every delivery event recorded in the window: delivered, bounced, deferred, rejected and dropped. It is NOT `delivered + bounced + failed` -- deferrals are counted in and are broken out nowhere in the response, so `sent` is normally larger than the three figures beside it. Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "delivered": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "bounced": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Messages a receiving server refused (`email.bounced`). Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "failed": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Permanent non-delivery: rejected plus dropped. A deferral is a retry, not a failure, and is not counted here. Null means the figure is unavailable, never that it is zero."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "series": {
                                                                                        "type": "array",
                                                                                        "description": "The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.",
                                                                                        "items": {
                                                                                            "type": "object",
                                                                                            "properties": {
                                                                                                "start_at": {
                                                                                                    "type": "string",
                                                                                                    "format": "date-time",
                                                                                                    "nullable": true,
                                                                                                    "description": "The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live."
                                                                                                },
                                                                                                "sent": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Every delivery event recorded in the window: delivered, bounced, deferred, rejected and dropped. It is NOT `delivered + bounced + failed` -- deferrals are counted in and are broken out nowhere in the response, so `sent` is normally larger than the three figures beside it. Null means the figure is unavailable, never that it is zero."
                                                                                                },
                                                                                                "delivered": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                                                },
                                                                                                "bounced": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Messages a receiving server refused (`email.bounced`). Null means the figure is unavailable, never that it is zero."
                                                                                                },
                                                                                                "failed": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Permanent non-delivery: rejected plus dropped. A deferral is a retry, not a failure, and is not counted here. Null means the figure is unavailable, never that it is zero."
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "bounce_reasons": {
                                                                                        "type": "array",
                                                                                        "description": "The ten most frequent bounce reasons in the window, most frequent first. There is no `percentage` on a row: it was `count / bounced`, and both numbers are already in this response.",
                                                                                        "items": {
                                                                                            "type": "object",
                                                                                            "properties": {
                                                                                                "reason": {
                                                                                                    "type": "string",
                                                                                                    "description": "The reason as the bounce event reported it. `unknown` is a real value here, not a null: it groups bounces whose payload carried no `bounce_reason`, and dropping them would make these counts fail to add up to `totals.bounced`."
                                                                                                },
                                                                                                "count": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Bounces in the window with this reason. Null means the figure is unavailable, never that it is zero."
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            },
                                                                            {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "object": {
                                                                                        "type": "string",
                                                                                        "enum": [
                                                                                            "engagement_report"
                                                                                        ]
                                                                                    },
                                                                                    "generated_at": {
                                                                                        "type": "string",
                                                                                        "format": "date-time",
                                                                                        "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                                    },
                                                                                    "period": {
                                                                                        "type": "object",
                                                                                        "nullable": true,
                                                                                        "description": "The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.",
                                                                                        "properties": {
                                                                                            "start_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "end_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "granularity": {
                                                                                                "type": "string",
                                                                                                "enum": [
                                                                                                    "day"
                                                                                                ],
                                                                                                "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "totals": {
                                                                                        "type": "object",
                                                                                        "description": "Engagement measured against DELIVERED mail. `delivered` is the denominator -- an open rate over messages that bounced is meaningless -- and it is the same number, under the same name, that `/reports/email-delivery` publishes. No `open_rate`, `click_rate` or `unsubscribe_rate`: divide by `delivered`.",
                                                                                        "properties": {
                                                                                            "delivered": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "opened": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Open events (`tracking.open`). Events, not people: one recipient opening twice counts twice. Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "clicked": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Click events (`tracking.click`). Events, not people. Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "unsubscribed": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Unsubscribe events (`tracking.unsubscribe`). Null means the figure is unavailable, never that it is zero."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "series": {
                                                                                        "type": "array",
                                                                                        "description": "The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.",
                                                                                        "items": {
                                                                                            "type": "object",
                                                                                            "properties": {
                                                                                                "start_at": {
                                                                                                    "type": "string",
                                                                                                    "format": "date-time",
                                                                                                    "nullable": true,
                                                                                                    "description": "The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live."
                                                                                                },
                                                                                                "delivered": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                                                },
                                                                                                "opened": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Open events (`tracking.open`). Events, not people: one recipient opening twice counts twice. Null means the figure is unavailable, never that it is zero."
                                                                                                },
                                                                                                "clicked": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Click events (`tracking.click`). Events, not people. Null means the figure is unavailable, never that it is zero."
                                                                                                },
                                                                                                "unsubscribed": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Unsubscribe events (`tracking.unsubscribe`). Null means the figure is unavailable, never that it is zero."
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            },
                                                                            {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "object": {
                                                                                        "type": "string",
                                                                                        "enum": [
                                                                                            "domain_health_report"
                                                                                        ]
                                                                                    },
                                                                                    "generated_at": {
                                                                                        "type": "string",
                                                                                        "format": "date-time",
                                                                                        "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                                    },
                                                                                    "period": {
                                                                                        "type": "object",
                                                                                        "nullable": true,
                                                                                        "description": "Always null. This report is a snapshot of current DNS state, not a windowed aggregate: `ReportService::domainHealth()` takes no date range and the `date_range` query parameter is ignored.",
                                                                                        "properties": {
                                                                                            "start_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "end_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "granularity": {
                                                                                                "type": "string",
                                                                                                "enum": [
                                                                                                    "day"
                                                                                                ],
                                                                                                "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "domains": {
                                                                                        "type": "array",
                                                                                        "description": "One row per domain in your organization, soft-deleted domains excluded.",
                                                                                        "items": {
                                                                                            "type": "object",
                                                                                            "properties": {
                                                                                                "object": {
                                                                                                    "type": "string",
                                                                                                    "enum": [
                                                                                                        "domain_health"
                                                                                                    ]
                                                                                                },
                                                                                                "domain": {
                                                                                                    "type": "string",
                                                                                                    "description": "The domain name. NOT NULLABLE, and that is a claim rather than an oversight: `domains.domain` is `varchar(255) NOT NULL UNIQUE` and the only producer reads it straight off the model, so there is no path that yields a row without one. Publishing it as nullable would have made every caller write a null check for a case that cannot occur, which is its own wrong promise. Pinned by PublicReportContractTest::test_a_domain_health_row_never_publishes_a_null_domain."
                                                                                                },
                                                                                                "dns": {
                                                                                                    "type": "object",
                                                                                                    "description": "The one lifecycle answer for this domain's DNS. The row used to carry the domains table's own `status` (\"Active\"/\"Inactive\") beside `dns_status`, which could disagree with it.",
                                                                                                    "properties": {
                                                                                                        "state": {
                                                                                                            "type": "string",
                                                                                                            "enum": [
                                                                                                                "verified",
                                                                                                                "pending",
                                                                                                                "failed",
                                                                                                                "unknown"
                                                                                                            ],
                                                                                                            "description": "Normalised and closed. The underlying column is free text and holds both `failed` and `Failed`, plus NULL for most rows; anything outside the three known values is `unknown`, which is why the buckets in `totals` always sum."
                                                                                                        },
                                                                                                        "verified": {
                                                                                                            "type": "boolean",
                                                                                                            "description": "True only for `verified`. `pending` and `failed` are both \"not verified\" to a caller deciding whether to send."
                                                                                                        }
                                                                                                    }
                                                                                                },
                                                                                                "spam_score": {
                                                                                                    "type": "number",
                                                                                                    "nullable": true,
                                                                                                    "description": "Always null today: nothing in this stack computes a spam score. Null rather than 0 because 0 would read as the worst possible verdict rather than as a gap. Kept in the shape because reputation IS domain health -- this report exists to answer it."
                                                                                                },
                                                                                                "reputation_score": {
                                                                                                    "type": "number",
                                                                                                    "nullable": true,
                                                                                                    "description": "Always null today, for the same reason as `spam_score`."
                                                                                                },
                                                                                                "checked_at": {
                                                                                                    "type": "string",
                                                                                                    "format": "date-time",
                                                                                                    "nullable": true,
                                                                                                    "description": "Sourced from the domain record's `updated_at`, so it moves whenever anything about the domain changes and is not necessarily when DNS was last checked. Treat it as \"as of\", not as a check timestamp."
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "totals": {
                                                                                        "type": "object",
                                                                                        "description": "DNS-state bucket counts, recounted from the rows above rather than copied from the service. `verified + pending + failed + unknown` always equals `domains`. NOTE these count domains, not messages: `failed` here is a DNS state, unrelated to the delivery report's `failed`.",
                                                                                        "properties": {
                                                                                            "domains": {
                                                                                                "type": "integer",
                                                                                                "description": "Rows in `domains`."
                                                                                            },
                                                                                            "verified": {
                                                                                                "type": "integer",
                                                                                                "description": "Domains whose DNS has passed."
                                                                                            },
                                                                                            "pending": {
                                                                                                "type": "integer",
                                                                                                "description": "Domains whose DNS check has not finished."
                                                                                            },
                                                                                            "failed": {
                                                                                                "type": "integer",
                                                                                                "description": "Domains whose DNS check failed."
                                                                                            },
                                                                                            "unknown": {
                                                                                                "type": "integer",
                                                                                                "description": "Domains whose `dns_config_status` is NULL or a value outside the closed set. Most domains sit here. Before the buckets were recounted, these were counted into nothing and the three buckets silently failed to add up to the number of domains."
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            },
                                                                            {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "object": {
                                                                                        "type": "string",
                                                                                        "enum": [
                                                                                            "volume_report"
                                                                                        ]
                                                                                    },
                                                                                    "generated_at": {
                                                                                        "type": "string",
                                                                                        "format": "date-time",
                                                                                        "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                                    },
                                                                                    "period": {
                                                                                        "type": "object",
                                                                                        "nullable": true,
                                                                                        "description": "The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.",
                                                                                        "properties": {
                                                                                            "start_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "end_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "granularity": {
                                                                                                "type": "string",
                                                                                                "enum": [
                                                                                                    "day"
                                                                                                ],
                                                                                                "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "totals": {
                                                                                        "type": "object",
                                                                                        "description": "The top-line counts. `average_daily_volume` and `peak_volume` are gone: both were one line of caller code over `series`, and both were computed from `events`, which is not a message count.",
                                                                                        "properties": {
                                                                                            "events": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "sent": {
                                                                                                "type": "integer",
                                                                                                "nullable": false,
                                                                                                "description": "In THIS report only, `sent` is `delivered + bounced` -- the messages that reached a receiving server and got a verdict. `/reports/email-delivery` publishes `sent` as five event types (deferrals, rejections and drops as well), so the same name returns a different and smaller number here. Do not compare the two directly. Recorded as a defect in plans/13-public-api-contract/converted/mailserver.md; the counts are published as the service computes them rather than quietly reconciled. Summed from `series`, so the two can never drift apart."
                                                                                            },
                                                                                            "received": {
                                                                                                "type": "integer",
                                                                                                "nullable": false,
                                                                                                "description": "Inbound mail (`email.inbound`). Summed from `series`."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "series": {
                                                                                        "type": "array",
                                                                                        "description": "The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.",
                                                                                        "items": {
                                                                                            "type": "object",
                                                                                            "properties": {
                                                                                                "start_at": {
                                                                                                    "type": "string",
                                                                                                    "format": "date-time",
                                                                                                    "nullable": true,
                                                                                                    "description": "The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live."
                                                                                                },
                                                                                                "events": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                                                },
                                                                                                "sent": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "In THIS report only, `sent` is `delivered + bounced` -- the messages that reached a receiving server and got a verdict. `/reports/email-delivery` publishes `sent` as five event types (deferrals, rejections and drops as well), so the same name returns a different and smaller number here. Do not compare the two directly. Recorded as a defect in plans/13-public-api-contract/converted/mailserver.md; the counts are published as the service computes them rather than quietly reconciled. Null means the figure is unavailable, never that it is zero."
                                                                                                },
                                                                                                "received": {
                                                                                                    "type": "integer",
                                                                                                    "nullable": true,
                                                                                                    "description": "Inbound mail (`email.inbound`). Null means the figure is unavailable, never that it is zero."
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "distributions": {
                                                                                        "type": "object",
                                                                                        "description": "Histograms, not time series, which is why they are not `series`. TWO CAVEATS, both unchanged behaviour: the buckets are SPARSE -- an hour or a weekday with no events has no row rather than a zero -- and they are cut on the SERVER's application timezone, not yours and not UTC, so a bucket label is only meaningful once you know that timezone. The `percentage` each row used to carry is gone; it duplicated `events` over `totals.events`.",
                                                                                        "properties": {
                                                                                            "hour_of_day": {
                                                                                                "type": "array",
                                                                                                "items": {
                                                                                                    "type": "object",
                                                                                                    "properties": {
                                                                                                        "bucket": {
                                                                                                            "type": "string",
                                                                                                            "description": "`\"00\"` to `\"23\"`."
                                                                                                        },
                                                                                                        "events": {
                                                                                                            "type": "integer",
                                                                                                            "nullable": true,
                                                                                                            "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                                                        }
                                                                                                    }
                                                                                                }
                                                                                            },
                                                                                            "day_of_week": {
                                                                                                "type": "array",
                                                                                                "items": {
                                                                                                    "type": "object",
                                                                                                    "properties": {
                                                                                                        "bucket": {
                                                                                                            "type": "string",
                                                                                                            "description": "`\"Monday\"` to `\"Sunday\"`, in English."
                                                                                                        },
                                                                                                        "events": {
                                                                                                            "type": "integer",
                                                                                                            "nullable": true,
                                                                                                            "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                                                        }
                                                                                                    }
                                                                                                }
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            },
                                                                            {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "object": {
                                                                                        "type": "string",
                                                                                        "enum": [
                                                                                            "security_report"
                                                                                        ]
                                                                                    },
                                                                                    "generated_at": {
                                                                                        "type": "string",
                                                                                        "format": "date-time",
                                                                                        "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                                    },
                                                                                    "period": {
                                                                                        "type": "object",
                                                                                        "nullable": true,
                                                                                        "description": "Null while `availability.state` is `unavailable`, which is every response today: there is no window because nothing was measured over one.",
                                                                                        "properties": {
                                                                                            "start_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "end_at": {
                                                                                                "type": "string",
                                                                                                "format": "date-time"
                                                                                            },
                                                                                            "granularity": {
                                                                                                "type": "string",
                                                                                                "enum": [
                                                                                                    "day"
                                                                                                ],
                                                                                                "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "availability": {
                                                                                        "type": "object",
                                                                                        "description": "Whether there is a detection engine behind these figures. Check this BEFORE reading `totals` -- the counts are null, not zero, while it says `unavailable`.",
                                                                                        "properties": {
                                                                                            "state": {
                                                                                                "type": "string",
                                                                                                "enum": [
                                                                                                    "available",
                                                                                                    "unavailable"
                                                                                                ],
                                                                                                "description": "Today always `unavailable`. No spam, malware or phishing detection data source exists yet in mailyte-api or the mail server."
                                                                                            },
                                                                                            "reason": {
                                                                                                "type": "string",
                                                                                                "nullable": true,
                                                                                                "description": "Why the figures are unavailable. Null when they are not."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "totals": {
                                                                                        "type": "object",
                                                                                        "description": "ALL NULL today, and that is the point. This endpoint used to answer `available: false` and then report zero spam, zero malware and zero phishing -- which is not \"no data\", it is a clean bill of health. A customer charting it saw a flat green line and a customer alerting on it never alerted. Null says \"we have not measured\"; treat it as unknown, never as none.",
                                                                                        "properties": {
                                                                                            "scanned": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Messages put through spam, malware and phishing detection. Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "spam": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Messages detection classified as spam. Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "malware": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Messages detection found malware in. Null means the figure is unavailable, never that it is zero."
                                                                                            },
                                                                                            "phishing": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Messages detection classified as phishing. Null means the figure is unavailable, never that it is zero."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "series": {
                                                                                        "type": "array",
                                                                                        "nullable": true,
                                                                                        "description": "Null while `availability.state` is `unavailable`, which is always. Nothing produces security trend rows, so publishing `[]` would assert there were no incidents. When a detection engine exists these rows will carry the section's standard `start_at` plus the counts above; only `availability.state` and the nulls change.",
                                                                                        "items": {
                                                                                            "type": "object"
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        ]
                                                                    },
                                                                    "requested_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When the build was ASKED for (`created_at`), which is what a caller polling a queue cares about. NULL MEANS UNKNOWN -- we do not know when it was requested -- and never \"it has not been requested yet\": the row exists only because somebody requested it. `report_generations.created_at` is a NULLABLE timestamp column (Laravel's `timestamps()` default), so a row written without touching the timestamps has none. Do not sort a queue on this field without handling the null."
                                                                    },
                                                                    "completed_at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "When the build finished, and it is only ever written on SUCCESS. Read it against `status`: while `pending` or `processing`, null means NOT YET; when `failed`, null means NONE and it will stay null forever, because the job's `failed()` hook sets `status` and `error` and never a finish time. So a null here is not a way to tell a running build from a dead one -- `status` is."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "pagination_meta": {
                                                            "$ref": "#/components/schemas/PaginationMeta"
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/reports/templates": {
            "get": {
                "operationId": "getReportsTemplates",
                "summary": "Templates (report)",
                "tags": [
                    "Reports"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "report_template"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "email-delivery",
                                                                    "domain-health",
                                                                    "engagement",
                                                                    "volume-trends"
                                                                ],
                                                                "description": "The value to send as `template_id` on `POST /reports/generate`. This list advertises FOUR templates while generate accepts FIVE -- it also accepts `security` -- so a client driving its UI from this endpoint can never offer the security report. Recorded in plans/13-public-api-contract/converted/mailserver.md."
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "description": "Display name. NOT NULLABLE: this endpoint is `ReportService::templates()`, a hardcoded array in this repository rather than anything fetched, so every row it can return is written out there with a name. See `parameters[].default` for the one field in this object that genuinely can be null."
                                                            },
                                                            "description": {
                                                                "type": "string",
                                                                "description": "One line about the report. Written before the rates were removed, so some still say \"rates\" where the report now publishes counts. NOT NULLABLE, for the same reason as `name`: the four rows are literals in this repository and all four carry one."
                                                            },
                                                            "parameters": {
                                                                "type": "array",
                                                                "description": "What this template accepts in the `parameters` object of `POST /reports/generate`. An EMPTY ARRAY is a real answer -- it means the template takes no parameters, which is `domain-health` today -- and is never a stand-in for \"we did not look\".",
                                                                "items": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "name": {
                                                                            "type": "string",
                                                                            "description": "The key to send inside `parameters`. NOT NULLABLE: these rows are literals in `ReportService::templates()`."
                                                                        },
                                                                        "type": {
                                                                            "type": "string",
                                                                            "enum": [
                                                                                "string"
                                                                            ],
                                                                            "description": "The JSON type of the value. A CLOSED set, and currently a set of one: every parameter of every template is a `string`. This is not an upstream field we forward -- the template list is a hardcoded array in this repository -- so the closed set is knowable, and a test asserts this enum still equals the distinct types the endpoint returns. NOT NULLABLE for the same reason as `name`. Note the values themselves are keyword strings, not free text: `date_range` is one of `day`, `week`, `month`, `quarter` and anything else is silently replaced with `month`."
                                                                        },
                                                                        "required": {
                                                                            "type": "boolean"
                                                                        },
                                                                        "default": {
                                                                            "nullable": true,
                                                                            "description": "What is used when you omit the parameter. Was `default_value`; the object already says these are parameters, and `_value` on a field called `default` is the same word twice. NULL MEANS NONE -- this parameter has no default -- not that we could not read one. Every parameter published today has one, so null is reachable only for a future `required: true` parameter with nothing to fall back to, and for such a parameter null is the correct answer rather than a gap."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/reports/generate": {
            "post": {
                "operationId": "postReportsGenerate",
                "summary": "Generate (report)",
                "tags": [
                    "Reports"
                ],
                "x-required-scope": "reports:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "report_generation"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "ULID. `POST /reports/generate` used to call this `report_id` and `GET /reports/history` called it `id`, so following a report you had just queued meant knowing the two were the same field. One name now, and a generate response IS a history row."
                                                        },
                                                        "template_id": {
                                                            "type": "string",
                                                            "enum": [
                                                                "email-delivery",
                                                                "domain-health",
                                                                "engagement",
                                                                "volume-trends",
                                                                "security"
                                                            ],
                                                            "description": "Matches the `id` of a row from `GET /reports/templates`. Note `security` is accepted here but is not advertised by that endpoint."
                                                        },
                                                        "format": {
                                                            "type": "string",
                                                            "enum": [
                                                                "pdf",
                                                                "csv",
                                                                "json"
                                                            ],
                                                            "description": "The format you asked for. The job stores a JSON snapshot whichever you ask for -- PDF and CSV rendering is not built -- so this records the request, not what `result` is."
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "enum": [
                                                                "pending",
                                                                "processing",
                                                                "completed",
                                                                "failed"
                                                            ],
                                                            "description": "Poll this. There is deliberately no `estimated_completion`: it was `now() + 30 seconds`, hardcoded and unrelated to the queue depth, the job or the report's size, so polling against it polled at the wrong time."
                                                        },
                                                        "parameters": {
                                                            "type": "object",
                                                            "additionalProperties": true,
                                                            "description": "What the report was queued with. Always an object: it is an array cast, so it used to serialise as `[]` when empty and `{}` otherwise, and a field whose JSON type changes with its contents is unusable from a typed language."
                                                        },
                                                        "error": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Why the build failed. Non-null only when `status` is `failed`. NULL MEANS NONE -- there is no error -- not that we lost the reason: the only two writers (`GenerateReportJob::handle()` and its `failed()` hook) set `status` and `error` in the same update, so a `failed` row always carries one and no other status ever does."
                                                        },
                                                        "result": {
                                                            "nullable": true,
                                                            "description": "The stored report, rendered through the SAME resource the live endpoint uses, so the vocabulary is identical whether you read a report live or out of history. Returning the raw snapshot would have re-published `total_volume`, `bounce_rate`, `total_sent` and the rest through the back door. Null while the job is queued, when it failed, and for a template we have no resource for. Its `period` is always null -- a snapshot keeps no record of the window it covered.",
                                                            "oneOf": [
                                                                {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "object": {
                                                                            "type": "string",
                                                                            "enum": [
                                                                                "email_delivery_report"
                                                                            ]
                                                                        },
                                                                        "generated_at": {
                                                                            "type": "string",
                                                                            "format": "date-time",
                                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                        },
                                                                        "period": {
                                                                            "type": "object",
                                                                            "nullable": true,
                                                                            "description": "The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.",
                                                                            "properties": {
                                                                                "start_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "end_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "granularity": {
                                                                                    "type": "string",
                                                                                    "enum": [
                                                                                        "day"
                                                                                    ],
                                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                }
                                                                            }
                                                                        },
                                                                        "totals": {
                                                                            "type": "object",
                                                                            "description": "The counts for the whole period. No rates: every rate this endpoint used to publish was arithmetic over counts sitting beside it, and two fields that can disagree -- which rounding guarantees -- are a bug report waiting to be filed. The counts are published; divide them yourself.",
                                                                            "properties": {
                                                                                "sent": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Every delivery event recorded in the window: delivered, bounced, deferred, rejected and dropped. It is NOT `delivered + bounced + failed` -- deferrals are counted in and are broken out nowhere in the response, so `sent` is normally larger than the three figures beside it. Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "delivered": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "bounced": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Messages a receiving server refused (`email.bounced`). Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "failed": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Permanent non-delivery: rejected plus dropped. A deferral is a retry, not a failure, and is not counted here. Null means the figure is unavailable, never that it is zero."
                                                                                }
                                                                            }
                                                                        },
                                                                        "series": {
                                                                            "type": "array",
                                                                            "description": "The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.",
                                                                            "items": {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "start_at": {
                                                                                        "type": "string",
                                                                                        "format": "date-time",
                                                                                        "nullable": true,
                                                                                        "description": "The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live."
                                                                                    },
                                                                                    "sent": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Every delivery event recorded in the window: delivered, bounced, deferred, rejected and dropped. It is NOT `delivered + bounced + failed` -- deferrals are counted in and are broken out nowhere in the response, so `sent` is normally larger than the three figures beside it. Null means the figure is unavailable, never that it is zero."
                                                                                    },
                                                                                    "delivered": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                                    },
                                                                                    "bounced": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Messages a receiving server refused (`email.bounced`). Null means the figure is unavailable, never that it is zero."
                                                                                    },
                                                                                    "failed": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Permanent non-delivery: rejected plus dropped. A deferral is a retry, not a failure, and is not counted here. Null means the figure is unavailable, never that it is zero."
                                                                                    }
                                                                                }
                                                                            }
                                                                        },
                                                                        "bounce_reasons": {
                                                                            "type": "array",
                                                                            "description": "The ten most frequent bounce reasons in the window, most frequent first. There is no `percentage` on a row: it was `count / bounced`, and both numbers are already in this response.",
                                                                            "items": {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "reason": {
                                                                                        "type": "string",
                                                                                        "description": "The reason as the bounce event reported it. `unknown` is a real value here, not a null: it groups bounces whose payload carried no `bounce_reason`, and dropping them would make these counts fail to add up to `totals.bounced`."
                                                                                    },
                                                                                    "count": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Bounces in the window with this reason. Null means the figure is unavailable, never that it is zero."
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "object": {
                                                                            "type": "string",
                                                                            "enum": [
                                                                                "engagement_report"
                                                                            ]
                                                                        },
                                                                        "generated_at": {
                                                                            "type": "string",
                                                                            "format": "date-time",
                                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                        },
                                                                        "period": {
                                                                            "type": "object",
                                                                            "nullable": true,
                                                                            "description": "The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.",
                                                                            "properties": {
                                                                                "start_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "end_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "granularity": {
                                                                                    "type": "string",
                                                                                    "enum": [
                                                                                        "day"
                                                                                    ],
                                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                }
                                                                            }
                                                                        },
                                                                        "totals": {
                                                                            "type": "object",
                                                                            "description": "Engagement measured against DELIVERED mail. `delivered` is the denominator -- an open rate over messages that bounced is meaningless -- and it is the same number, under the same name, that `/reports/email-delivery` publishes. No `open_rate`, `click_rate` or `unsubscribe_rate`: divide by `delivered`.",
                                                                            "properties": {
                                                                                "delivered": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "opened": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Open events (`tracking.open`). Events, not people: one recipient opening twice counts twice. Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "clicked": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Click events (`tracking.click`). Events, not people. Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "unsubscribed": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Unsubscribe events (`tracking.unsubscribe`). Null means the figure is unavailable, never that it is zero."
                                                                                }
                                                                            }
                                                                        },
                                                                        "series": {
                                                                            "type": "array",
                                                                            "description": "The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.",
                                                                            "items": {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "start_at": {
                                                                                        "type": "string",
                                                                                        "format": "date-time",
                                                                                        "nullable": true,
                                                                                        "description": "The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live."
                                                                                    },
                                                                                    "delivered": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Messages a receiving server accepted (`email.delivered`). This is the denominator to divide the engagement counts by. Null means the figure is unavailable, never that it is zero."
                                                                                    },
                                                                                    "opened": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Open events (`tracking.open`). Events, not people: one recipient opening twice counts twice. Null means the figure is unavailable, never that it is zero."
                                                                                    },
                                                                                    "clicked": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Click events (`tracking.click`). Events, not people. Null means the figure is unavailable, never that it is zero."
                                                                                    },
                                                                                    "unsubscribed": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Unsubscribe events (`tracking.unsubscribe`). Null means the figure is unavailable, never that it is zero."
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "object": {
                                                                            "type": "string",
                                                                            "enum": [
                                                                                "domain_health_report"
                                                                            ]
                                                                        },
                                                                        "generated_at": {
                                                                            "type": "string",
                                                                            "format": "date-time",
                                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                        },
                                                                        "period": {
                                                                            "type": "object",
                                                                            "nullable": true,
                                                                            "description": "Always null. This report is a snapshot of current DNS state, not a windowed aggregate: `ReportService::domainHealth()` takes no date range and the `date_range` query parameter is ignored.",
                                                                            "properties": {
                                                                                "start_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "end_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "granularity": {
                                                                                    "type": "string",
                                                                                    "enum": [
                                                                                        "day"
                                                                                    ],
                                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                }
                                                                            }
                                                                        },
                                                                        "domains": {
                                                                            "type": "array",
                                                                            "description": "One row per domain in your organization, soft-deleted domains excluded.",
                                                                            "items": {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "object": {
                                                                                        "type": "string",
                                                                                        "enum": [
                                                                                            "domain_health"
                                                                                        ]
                                                                                    },
                                                                                    "domain": {
                                                                                        "type": "string",
                                                                                        "description": "The domain name. NOT NULLABLE, and that is a claim rather than an oversight: `domains.domain` is `varchar(255) NOT NULL UNIQUE` and the only producer reads it straight off the model, so there is no path that yields a row without one. Publishing it as nullable would have made every caller write a null check for a case that cannot occur, which is its own wrong promise. Pinned by PublicReportContractTest::test_a_domain_health_row_never_publishes_a_null_domain."
                                                                                    },
                                                                                    "dns": {
                                                                                        "type": "object",
                                                                                        "description": "The one lifecycle answer for this domain's DNS. The row used to carry the domains table's own `status` (\"Active\"/\"Inactive\") beside `dns_status`, which could disagree with it.",
                                                                                        "properties": {
                                                                                            "state": {
                                                                                                "type": "string",
                                                                                                "enum": [
                                                                                                    "verified",
                                                                                                    "pending",
                                                                                                    "failed",
                                                                                                    "unknown"
                                                                                                ],
                                                                                                "description": "Normalised and closed. The underlying column is free text and holds both `failed` and `Failed`, plus NULL for most rows; anything outside the three known values is `unknown`, which is why the buckets in `totals` always sum."
                                                                                            },
                                                                                            "verified": {
                                                                                                "type": "boolean",
                                                                                                "description": "True only for `verified`. `pending` and `failed` are both \"not verified\" to a caller deciding whether to send."
                                                                                            }
                                                                                        }
                                                                                    },
                                                                                    "spam_score": {
                                                                                        "type": "number",
                                                                                        "nullable": true,
                                                                                        "description": "Always null today: nothing in this stack computes a spam score. Null rather than 0 because 0 would read as the worst possible verdict rather than as a gap. Kept in the shape because reputation IS domain health -- this report exists to answer it."
                                                                                    },
                                                                                    "reputation_score": {
                                                                                        "type": "number",
                                                                                        "nullable": true,
                                                                                        "description": "Always null today, for the same reason as `spam_score`."
                                                                                    },
                                                                                    "checked_at": {
                                                                                        "type": "string",
                                                                                        "format": "date-time",
                                                                                        "nullable": true,
                                                                                        "description": "Sourced from the domain record's `updated_at`, so it moves whenever anything about the domain changes and is not necessarily when DNS was last checked. Treat it as \"as of\", not as a check timestamp."
                                                                                    }
                                                                                }
                                                                            }
                                                                        },
                                                                        "totals": {
                                                                            "type": "object",
                                                                            "description": "DNS-state bucket counts, recounted from the rows above rather than copied from the service. `verified + pending + failed + unknown` always equals `domains`. NOTE these count domains, not messages: `failed` here is a DNS state, unrelated to the delivery report's `failed`.",
                                                                            "properties": {
                                                                                "domains": {
                                                                                    "type": "integer",
                                                                                    "description": "Rows in `domains`."
                                                                                },
                                                                                "verified": {
                                                                                    "type": "integer",
                                                                                    "description": "Domains whose DNS has passed."
                                                                                },
                                                                                "pending": {
                                                                                    "type": "integer",
                                                                                    "description": "Domains whose DNS check has not finished."
                                                                                },
                                                                                "failed": {
                                                                                    "type": "integer",
                                                                                    "description": "Domains whose DNS check failed."
                                                                                },
                                                                                "unknown": {
                                                                                    "type": "integer",
                                                                                    "description": "Domains whose `dns_config_status` is NULL or a value outside the closed set. Most domains sit here. Before the buckets were recounted, these were counted into nothing and the three buckets silently failed to add up to the number of domains."
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "object": {
                                                                            "type": "string",
                                                                            "enum": [
                                                                                "volume_report"
                                                                            ]
                                                                        },
                                                                        "generated_at": {
                                                                            "type": "string",
                                                                            "format": "date-time",
                                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                        },
                                                                        "period": {
                                                                            "type": "object",
                                                                            "nullable": true,
                                                                            "description": "The window this report actually covers, which is not always the window you asked for: a `date_range` outside `day`, `week`, `month` and `quarter` is silently replaced with `month`, so a request for `year` returns thirty days and this object is the only place that says so. Null when the report covers no window -- a stored result read back from `/reports/history` keeps no record of the window it was built over, and inventing one from your current query would describe the query rather than the data.",
                                                                            "properties": {
                                                                                "start_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "end_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "granularity": {
                                                                                    "type": "string",
                                                                                    "enum": [
                                                                                        "day"
                                                                                    ],
                                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                }
                                                                            }
                                                                        },
                                                                        "totals": {
                                                                            "type": "object",
                                                                            "description": "The top-line counts. `average_daily_volume` and `peak_volume` are gone: both were one line of caller code over `series`, and both were computed from `events`, which is not a message count.",
                                                                            "properties": {
                                                                                "events": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "sent": {
                                                                                    "type": "integer",
                                                                                    "nullable": false,
                                                                                    "description": "In THIS report only, `sent` is `delivered + bounced` -- the messages that reached a receiving server and got a verdict. `/reports/email-delivery` publishes `sent` as five event types (deferrals, rejections and drops as well), so the same name returns a different and smaller number here. Do not compare the two directly. Recorded as a defect in plans/13-public-api-contract/converted/mailserver.md; the counts are published as the service computes them rather than quietly reconciled. Summed from `series`, so the two can never drift apart."
                                                                                },
                                                                                "received": {
                                                                                    "type": "integer",
                                                                                    "nullable": false,
                                                                                    "description": "Inbound mail (`email.inbound`). Summed from `series`."
                                                                                }
                                                                            }
                                                                        },
                                                                        "series": {
                                                                            "type": "array",
                                                                            "description": "The same counts bucketed over the period, oldest first. Rows are SPARSE: a bucket in which nothing happened has no row at all, rather than a row of zeros, so do not index this array by day offset.",
                                                                            "items": {
                                                                                "type": "object",
                                                                                "properties": {
                                                                                    "start_at": {
                                                                                        "type": "string",
                                                                                        "format": "date-time",
                                                                                        "nullable": true,
                                                                                        "description": "The instant this bucket opens, midnight UTC. Replaces the bare `2026-09-17` these rows used to carry, which named no timezone. NULL MEANS UNKNOWN -- we could not read this bucket's boundary -- and never that the bucket has no start or is empty. A LIVE report cannot produce it: the rows are grouped by `delivery_events.created_at`, which is NOT NULL, so every bucket is keyed by a real date. It is reachable only through `GET /reports/history`, where the row is JSON written by whichever version of the report ran at the time and re-rendered through this same resource WITHOUT being re-validated; a stored row carrying no date becomes null here rather than being silently dated today. Drop such a row or read the report live."
                                                                                    },
                                                                                    "events": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                                    },
                                                                                    "sent": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "In THIS report only, `sent` is `delivered + bounced` -- the messages that reached a receiving server and got a verdict. `/reports/email-delivery` publishes `sent` as five event types (deferrals, rejections and drops as well), so the same name returns a different and smaller number here. Do not compare the two directly. Recorded as a defect in plans/13-public-api-contract/converted/mailserver.md; the counts are published as the service computes them rather than quietly reconciled. Null means the figure is unavailable, never that it is zero."
                                                                                    },
                                                                                    "received": {
                                                                                        "type": "integer",
                                                                                        "nullable": true,
                                                                                        "description": "Inbound mail (`email.inbound`). Null means the figure is unavailable, never that it is zero."
                                                                                    }
                                                                                }
                                                                            }
                                                                        },
                                                                        "distributions": {
                                                                            "type": "object",
                                                                            "description": "Histograms, not time series, which is why they are not `series`. TWO CAVEATS, both unchanged behaviour: the buckets are SPARSE -- an hour or a weekday with no events has no row rather than a zero -- and they are cut on the SERVER's application timezone, not yours and not UTC, so a bucket label is only meaningful once you know that timezone. The `percentage` each row used to carry is gone; it duplicated `events` over `totals.events`.",
                                                                            "properties": {
                                                                                "hour_of_day": {
                                                                                    "type": "array",
                                                                                    "items": {
                                                                                        "type": "object",
                                                                                        "properties": {
                                                                                            "bucket": {
                                                                                                "type": "string",
                                                                                                "description": "`\"00\"` to `\"23\"`."
                                                                                            },
                                                                                            "events": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                },
                                                                                "day_of_week": {
                                                                                    "type": "array",
                                                                                    "items": {
                                                                                        "type": "object",
                                                                                        "properties": {
                                                                                            "bucket": {
                                                                                                "type": "string",
                                                                                                "description": "`\"Monday\"` to `\"Sunday\"`, in English."
                                                                                            },
                                                                                            "events": {
                                                                                                "type": "integer",
                                                                                                "nullable": true,
                                                                                                "description": "Every `delivery_events` row in the window, tracking included -- opens, clicks and unsubscribes as well as sends. NOT a message count: it is roughly the message count multiplied by how much the recipients engaged. Null means the figure is unavailable, never that it is zero."
                                                                                            }
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                },
                                                                {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "object": {
                                                                            "type": "string",
                                                                            "enum": [
                                                                                "security_report"
                                                                            ]
                                                                        },
                                                                        "generated_at": {
                                                                            "type": "string",
                                                                            "format": "date-time",
                                                                            "description": "When this response was computed, ISO 8601 UTC. Every report answers it, so \"is this figure stale?\" never depends on which report you asked."
                                                                        },
                                                                        "period": {
                                                                            "type": "object",
                                                                            "nullable": true,
                                                                            "description": "Null while `availability.state` is `unavailable`, which is every response today: there is no window because nothing was measured over one.",
                                                                            "properties": {
                                                                                "start_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "end_at": {
                                                                                    "type": "string",
                                                                                    "format": "date-time"
                                                                                },
                                                                                "granularity": {
                                                                                    "type": "string",
                                                                                    "enum": [
                                                                                        "day"
                                                                                    ],
                                                                                    "description": "The width of one `series` bucket. Always `day`: the `granularity` query parameter is accepted and ignored."
                                                                                }
                                                                            }
                                                                        },
                                                                        "availability": {
                                                                            "type": "object",
                                                                            "description": "Whether there is a detection engine behind these figures. Check this BEFORE reading `totals` -- the counts are null, not zero, while it says `unavailable`.",
                                                                            "properties": {
                                                                                "state": {
                                                                                    "type": "string",
                                                                                    "enum": [
                                                                                        "available",
                                                                                        "unavailable"
                                                                                    ],
                                                                                    "description": "Today always `unavailable`. No spam, malware or phishing detection data source exists yet in mailyte-api or the mail server."
                                                                                },
                                                                                "reason": {
                                                                                    "type": "string",
                                                                                    "nullable": true,
                                                                                    "description": "Why the figures are unavailable. Null when they are not."
                                                                                }
                                                                            }
                                                                        },
                                                                        "totals": {
                                                                            "type": "object",
                                                                            "description": "ALL NULL today, and that is the point. This endpoint used to answer `available: false` and then report zero spam, zero malware and zero phishing -- which is not \"no data\", it is a clean bill of health. A customer charting it saw a flat green line and a customer alerting on it never alerted. Null says \"we have not measured\"; treat it as unknown, never as none.",
                                                                            "properties": {
                                                                                "scanned": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Messages put through spam, malware and phishing detection. Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "spam": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Messages detection classified as spam. Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "malware": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Messages detection found malware in. Null means the figure is unavailable, never that it is zero."
                                                                                },
                                                                                "phishing": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Messages detection classified as phishing. Null means the figure is unavailable, never that it is zero."
                                                                                }
                                                                            }
                                                                        },
                                                                        "series": {
                                                                            "type": "array",
                                                                            "nullable": true,
                                                                            "description": "Null while `availability.state` is `unavailable`, which is always. Nothing produces security trend rows, so publishing `[]` would assert there were no incidents. When a detection engine exists these rows will carry the section's standard `start_at` plus the counts above; only `availability.state` and the nulls change.",
                                                                            "items": {
                                                                                "type": "object"
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            ]
                                                        },
                                                        "requested_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the build was ASKED for (`created_at`), which is what a caller polling a queue cares about. NULL MEANS UNKNOWN -- we do not know when it was requested -- and never \"it has not been requested yet\": the row exists only because somebody requested it. `report_generations.created_at` is a NULLABLE timestamp column (Laravel's `timestamps()` default), so a row written without touching the timestamps has none. Do not sort a queue on this field without handling the null."
                                                        },
                                                        "completed_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the build finished, and it is only ever written on SUCCESS. Read it against `status`: while `pending` or `processing`, null means NOT YET; when `failed`, null means NONE and it will stay null forever, because the job's `failed()` hook sets `status` and `error` and never a finish time. So a null here is not a way to tell a running build from a dead one -- `status` is."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/transport-rules": {
            "get": {
                "operationId": "getTransportRules",
                "summary": "List transport rules",
                "tags": [
                    "Transport rules"
                ],
                "x-required-scope": "transport_rules:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "transport_rule"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "ULID, issued by the mail server. These arrive UPPERCASE (`01M2RV5CEM4MT97RQ00ANRRFCP`) while every Laravel-issued id in the product is lowercase. Both are valid Crockford base32; compare them exactly rather than case-insensitively, because we do not normalise an id we have already issued. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "The rule's display name, required on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                            },
                                                            "description": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "Free text about the rule. NULL MEANS NONE -- the rule genuinely has no description -- and this is the ONE field on a transport rule where that is what null means. Upstream declares it `description: str | None`, the only optional field on the response model, and `null` round-trips through create unchanged. Everything else nullable on this object is a null we could not read; see `id`."
                                                            },
                                                            "direction": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "enum": [
                                                                    "inbound",
                                                                    "outbound",
                                                                    "both"
                                                                ],
                                                                "description": "Which mail the rule is evaluated against. Defaults to `both` on create, so null is never \"unset\". NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                            },
                                                            "enabled": {
                                                                "type": "boolean",
                                                                "description": "A disabled rule keeps its priority and is not evaluated."
                                                            },
                                                            "priority": {
                                                                "type": "integer",
                                                                "nullable": true,
                                                                "description": "LOWER RUNS FIRST. `PUT /transport-rules/reorder` rewrites these in steps of 10 so a rule can be inserted between two others without renumbering the set. Defaults to 100 on create, so null is never \"no priority\" and must not be sorted as 0, which would run the rule FIRST. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                            },
                                                            "match": {
                                                                "type": "object",
                                                                "description": "How a message is matched. Was two top-level fields, `condition_logic` and `conditions`, with the prefix doing the grouping; grouped so you can hand the whole matcher to whatever evaluates it.",
                                                                "properties": {
                                                                    "logic": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "enum": [
                                                                            "all",
                                                                            "any"
                                                                        ],
                                                                        "description": "`all` requires every condition, `any` requires one. Defaults to `all` on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it. In particular do NOT read a null as `any`: that would widen a rule from \"every condition\" to \"any condition\" and apply its actions to mail it was never meant to touch."
                                                                    },
                                                                    "conditions": {
                                                                        "type": "array",
                                                                        "description": "Key order is fixed at `field`, `operator`, `value`. Upstream returns `{field, value, operator}` on read and accepts `{field, operator, value}` on write, so the same rule changed shape round-tripping through this API without changing meaning.",
                                                                        "items": {
                                                                            "type": "object",
                                                                            "properties": {
                                                                                "field": {
                                                                                    "type": "string",
                                                                                    "nullable": true,
                                                                                    "enum": [
                                                                                        "sender",
                                                                                        "recipient",
                                                                                        "subject",
                                                                                        "header",
                                                                                        "size",
                                                                                        "has_attachment"
                                                                                    ],
                                                                                    "description": "What is examined. `size` is the message size in bytes; `has_attachment` is a boolean test. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                                },
                                                                                "operator": {
                                                                                    "type": "string",
                                                                                    "nullable": true,
                                                                                    "enum": [
                                                                                        "equals",
                                                                                        "contains",
                                                                                        "starts_with",
                                                                                        "ends_with",
                                                                                        "regex",
                                                                                        "greater_than",
                                                                                        "less_than"
                                                                                    ],
                                                                                    "description": "How `value` is compared against `field`. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                                },
                                                                                "value": {
                                                                                    "type": "string",
                                                                                    "nullable": true,
                                                                                    "description": "What to compare against. ALWAYS A STRING, including for the numeric operators: a `size greater_than` condition reads back as `\"1048576\"`, quoted, because both our request rules (`conditions.*.value` => `required|string`) and upstream's `TransportRuleCondition.value: str` type it that way, and the column stores what they accepted. Parse it yourself for `greater_than` / `less_than`. (Published untyped until phase 3; a caller reading the old description would have expected a number here and got a numeric string.) NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            },
                                                            "actions": {
                                                                "type": "array",
                                                                "description": "What happens to a matched message, in order.",
                                                                "items": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "type": {
                                                                            "type": "string",
                                                                            "nullable": true,
                                                                            "enum": [
                                                                                "add_header",
                                                                                "modify_subject",
                                                                                "redirect",
                                                                                "bcc",
                                                                                "reject",
                                                                                "add_disclaimer",
                                                                                "quarantine"
                                                                            ],
                                                                            "description": "What is done to a matched message. NULL MEANS UNKNOWN -- the stored action carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `actions` as a bare `list[dict]` on its response model, so the `transport_rules.actions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the action as uninterpretable rather than guessing at it. A null is NOT \"do nothing\": the enforcer reads the same column, so an action you cannot name is one you cannot rule out either."
                                                                        },
                                                                        "params": {
                                                                            "type": "object",
                                                                            "additionalProperties": true,
                                                                            "description": "The action's parameters, keyed by name. ALWAYS an object: it was a PHP array, so it serialised as `[]` when empty and `{}` otherwise, and an action with no parameters must not be a different JSON type from one with some."
                                                                        }
                                                                    }
                                                                }
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true,
                                                                "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                            },
                                                            "updated_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true,
                                                                "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "operationId": "postTransportRules",
                "summary": "Create a transport rule",
                "tags": [
                    "Transport rules"
                ],
                "x-required-scope": "transport_rules:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transport_rule"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "ULID, issued by the mail server. These arrive UPPERCASE (`01M2RV5CEM4MT97RQ00ANRRFCP`) while every Laravel-issued id in the product is lowercase. Both are valid Crockford base32; compare them exactly rather than case-insensitively, because we do not normalise an id we have already issued. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The rule's display name, required on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Free text about the rule. NULL MEANS NONE -- the rule genuinely has no description -- and this is the ONE field on a transport rule where that is what null means. Upstream declares it `description: str | None`, the only optional field on the response model, and `null` round-trips through create unchanged. Everything else nullable on this object is a null we could not read; see `id`."
                                                        },
                                                        "direction": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "enum": [
                                                                "inbound",
                                                                "outbound",
                                                                "both"
                                                            ],
                                                            "description": "Which mail the rule is evaluated against. Defaults to `both` on create, so null is never \"unset\". NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "enabled": {
                                                            "type": "boolean",
                                                            "description": "A disabled rule keeps its priority and is not evaluated."
                                                        },
                                                        "priority": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "LOWER RUNS FIRST. `PUT /transport-rules/reorder` rewrites these in steps of 10 so a rule can be inserted between two others without renumbering the set. Defaults to 100 on create, so null is never \"no priority\" and must not be sorted as 0, which would run the rule FIRST. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "match": {
                                                            "type": "object",
                                                            "description": "How a message is matched. Was two top-level fields, `condition_logic` and `conditions`, with the prefix doing the grouping; grouped so you can hand the whole matcher to whatever evaluates it.",
                                                            "properties": {
                                                                "logic": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "all",
                                                                        "any"
                                                                    ],
                                                                    "description": "`all` requires every condition, `any` requires one. Defaults to `all` on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it. In particular do NOT read a null as `any`: that would widen a rule from \"every condition\" to \"any condition\" and apply its actions to mail it was never meant to touch."
                                                                },
                                                                "conditions": {
                                                                    "type": "array",
                                                                    "description": "Key order is fixed at `field`, `operator`, `value`. Upstream returns `{field, value, operator}` on read and accepts `{field, operator, value}` on write, so the same rule changed shape round-tripping through this API without changing meaning.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "field": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "enum": [
                                                                                    "sender",
                                                                                    "recipient",
                                                                                    "subject",
                                                                                    "header",
                                                                                    "size",
                                                                                    "has_attachment"
                                                                                ],
                                                                                "description": "What is examined. `size` is the message size in bytes; `has_attachment` is a boolean test. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            },
                                                                            "operator": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "enum": [
                                                                                    "equals",
                                                                                    "contains",
                                                                                    "starts_with",
                                                                                    "ends_with",
                                                                                    "regex",
                                                                                    "greater_than",
                                                                                    "less_than"
                                                                                ],
                                                                                "description": "How `value` is compared against `field`. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            },
                                                                            "value": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "What to compare against. ALWAYS A STRING, including for the numeric operators: a `size greater_than` condition reads back as `\"1048576\"`, quoted, because both our request rules (`conditions.*.value` => `required|string`) and upstream's `TransportRuleCondition.value: str` type it that way, and the column stores what they accepted. Parse it yourself for `greater_than` / `less_than`. (Published untyped until phase 3; a caller reading the old description would have expected a number here and got a numeric string.) NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "actions": {
                                                            "type": "array",
                                                            "description": "What happens to a matched message, in order.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "type": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "enum": [
                                                                            "add_header",
                                                                            "modify_subject",
                                                                            "redirect",
                                                                            "bcc",
                                                                            "reject",
                                                                            "add_disclaimer",
                                                                            "quarantine"
                                                                        ],
                                                                        "description": "What is done to a matched message. NULL MEANS UNKNOWN -- the stored action carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `actions` as a bare `list[dict]` on its response model, so the `transport_rules.actions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the action as uninterpretable rather than guessing at it. A null is NOT \"do nothing\": the enforcer reads the same column, so an action you cannot name is one you cannot rule out either."
                                                                    },
                                                                    "params": {
                                                                        "type": "object",
                                                                        "additionalProperties": true,
                                                                        "description": "The action's parameters, keyed by name. ALWAYS an object: it was a PHP array, so it serialised as `[]` when empty and `{}` otherwise, and an action with no parameters must not be a different JSON type from one with some."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/transport-rules/{id}": {
            "get": {
                "operationId": "getTransportRulesId",
                "summary": "Retrieve a transport rule",
                "tags": [
                    "Transport rules"
                ],
                "x-required-scope": "transport_rules:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "The id identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transport_rule"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "ULID, issued by the mail server. These arrive UPPERCASE (`01M2RV5CEM4MT97RQ00ANRRFCP`) while every Laravel-issued id in the product is lowercase. Both are valid Crockford base32; compare them exactly rather than case-insensitively, because we do not normalise an id we have already issued. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The rule's display name, required on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Free text about the rule. NULL MEANS NONE -- the rule genuinely has no description -- and this is the ONE field on a transport rule where that is what null means. Upstream declares it `description: str | None`, the only optional field on the response model, and `null` round-trips through create unchanged. Everything else nullable on this object is a null we could not read; see `id`."
                                                        },
                                                        "direction": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "enum": [
                                                                "inbound",
                                                                "outbound",
                                                                "both"
                                                            ],
                                                            "description": "Which mail the rule is evaluated against. Defaults to `both` on create, so null is never \"unset\". NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "enabled": {
                                                            "type": "boolean",
                                                            "description": "A disabled rule keeps its priority and is not evaluated."
                                                        },
                                                        "priority": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "LOWER RUNS FIRST. `PUT /transport-rules/reorder` rewrites these in steps of 10 so a rule can be inserted between two others without renumbering the set. Defaults to 100 on create, so null is never \"no priority\" and must not be sorted as 0, which would run the rule FIRST. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "match": {
                                                            "type": "object",
                                                            "description": "How a message is matched. Was two top-level fields, `condition_logic` and `conditions`, with the prefix doing the grouping; grouped so you can hand the whole matcher to whatever evaluates it.",
                                                            "properties": {
                                                                "logic": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "all",
                                                                        "any"
                                                                    ],
                                                                    "description": "`all` requires every condition, `any` requires one. Defaults to `all` on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it. In particular do NOT read a null as `any`: that would widen a rule from \"every condition\" to \"any condition\" and apply its actions to mail it was never meant to touch."
                                                                },
                                                                "conditions": {
                                                                    "type": "array",
                                                                    "description": "Key order is fixed at `field`, `operator`, `value`. Upstream returns `{field, value, operator}` on read and accepts `{field, operator, value}` on write, so the same rule changed shape round-tripping through this API without changing meaning.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "field": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "enum": [
                                                                                    "sender",
                                                                                    "recipient",
                                                                                    "subject",
                                                                                    "header",
                                                                                    "size",
                                                                                    "has_attachment"
                                                                                ],
                                                                                "description": "What is examined. `size` is the message size in bytes; `has_attachment` is a boolean test. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            },
                                                                            "operator": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "enum": [
                                                                                    "equals",
                                                                                    "contains",
                                                                                    "starts_with",
                                                                                    "ends_with",
                                                                                    "regex",
                                                                                    "greater_than",
                                                                                    "less_than"
                                                                                ],
                                                                                "description": "How `value` is compared against `field`. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            },
                                                                            "value": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "What to compare against. ALWAYS A STRING, including for the numeric operators: a `size greater_than` condition reads back as `\"1048576\"`, quoted, because both our request rules (`conditions.*.value` => `required|string`) and upstream's `TransportRuleCondition.value: str` type it that way, and the column stores what they accepted. Parse it yourself for `greater_than` / `less_than`. (Published untyped until phase 3; a caller reading the old description would have expected a number here and got a numeric string.) NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "actions": {
                                                            "type": "array",
                                                            "description": "What happens to a matched message, in order.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "type": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "enum": [
                                                                            "add_header",
                                                                            "modify_subject",
                                                                            "redirect",
                                                                            "bcc",
                                                                            "reject",
                                                                            "add_disclaimer",
                                                                            "quarantine"
                                                                        ],
                                                                        "description": "What is done to a matched message. NULL MEANS UNKNOWN -- the stored action carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `actions` as a bare `list[dict]` on its response model, so the `transport_rules.actions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the action as uninterpretable rather than guessing at it. A null is NOT \"do nothing\": the enforcer reads the same column, so an action you cannot name is one you cannot rule out either."
                                                                    },
                                                                    "params": {
                                                                        "type": "object",
                                                                        "additionalProperties": true,
                                                                        "description": "The action's parameters, keyed by name. ALWAYS an object: it was a PHP array, so it serialised as `[]` when empty and `{}` otherwise, and an action with no parameters must not be a different JSON type from one with some."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "operationId": "putTransportRulesId",
                "summary": "Update a transport rule",
                "tags": [
                    "Transport rules"
                ],
                "x-required-scope": "transport_rules:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "The id identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transport_rule"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "ULID, issued by the mail server. These arrive UPPERCASE (`01M2RV5CEM4MT97RQ00ANRRFCP`) while every Laravel-issued id in the product is lowercase. Both are valid Crockford base32; compare them exactly rather than case-insensitively, because we do not normalise an id we have already issued. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The rule's display name, required on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Free text about the rule. NULL MEANS NONE -- the rule genuinely has no description -- and this is the ONE field on a transport rule where that is what null means. Upstream declares it `description: str | None`, the only optional field on the response model, and `null` round-trips through create unchanged. Everything else nullable on this object is a null we could not read; see `id`."
                                                        },
                                                        "direction": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "enum": [
                                                                "inbound",
                                                                "outbound",
                                                                "both"
                                                            ],
                                                            "description": "Which mail the rule is evaluated against. Defaults to `both` on create, so null is never \"unset\". NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "enabled": {
                                                            "type": "boolean",
                                                            "description": "A disabled rule keeps its priority and is not evaluated."
                                                        },
                                                        "priority": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "LOWER RUNS FIRST. `PUT /transport-rules/reorder` rewrites these in steps of 10 so a rule can be inserted between two others without renumbering the set. Defaults to 100 on create, so null is never \"no priority\" and must not be sorted as 0, which would run the rule FIRST. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "match": {
                                                            "type": "object",
                                                            "description": "How a message is matched. Was two top-level fields, `condition_logic` and `conditions`, with the prefix doing the grouping; grouped so you can hand the whole matcher to whatever evaluates it.",
                                                            "properties": {
                                                                "logic": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "all",
                                                                        "any"
                                                                    ],
                                                                    "description": "`all` requires every condition, `any` requires one. Defaults to `all` on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it. In particular do NOT read a null as `any`: that would widen a rule from \"every condition\" to \"any condition\" and apply its actions to mail it was never meant to touch."
                                                                },
                                                                "conditions": {
                                                                    "type": "array",
                                                                    "description": "Key order is fixed at `field`, `operator`, `value`. Upstream returns `{field, value, operator}` on read and accepts `{field, operator, value}` on write, so the same rule changed shape round-tripping through this API without changing meaning.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "field": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "enum": [
                                                                                    "sender",
                                                                                    "recipient",
                                                                                    "subject",
                                                                                    "header",
                                                                                    "size",
                                                                                    "has_attachment"
                                                                                ],
                                                                                "description": "What is examined. `size` is the message size in bytes; `has_attachment` is a boolean test. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            },
                                                                            "operator": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "enum": [
                                                                                    "equals",
                                                                                    "contains",
                                                                                    "starts_with",
                                                                                    "ends_with",
                                                                                    "regex",
                                                                                    "greater_than",
                                                                                    "less_than"
                                                                                ],
                                                                                "description": "How `value` is compared against `field`. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            },
                                                                            "value": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "What to compare against. ALWAYS A STRING, including for the numeric operators: a `size greater_than` condition reads back as `\"1048576\"`, quoted, because both our request rules (`conditions.*.value` => `required|string`) and upstream's `TransportRuleCondition.value: str` type it that way, and the column stores what they accepted. Parse it yourself for `greater_than` / `less_than`. (Published untyped until phase 3; a caller reading the old description would have expected a number here and got a numeric string.) NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "actions": {
                                                            "type": "array",
                                                            "description": "What happens to a matched message, in order.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "type": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "enum": [
                                                                            "add_header",
                                                                            "modify_subject",
                                                                            "redirect",
                                                                            "bcc",
                                                                            "reject",
                                                                            "add_disclaimer",
                                                                            "quarantine"
                                                                        ],
                                                                        "description": "What is done to a matched message. NULL MEANS UNKNOWN -- the stored action carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `actions` as a bare `list[dict]` on its response model, so the `transport_rules.actions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the action as uninterpretable rather than guessing at it. A null is NOT \"do nothing\": the enforcer reads the same column, so an action you cannot name is one you cannot rule out either."
                                                                    },
                                                                    "params": {
                                                                        "type": "object",
                                                                        "additionalProperties": true,
                                                                        "description": "The action's parameters, keyed by name. ALWAYS an object: it was a PHP array, so it serialised as `[]` when empty and `{}` otherwise, and an action with no parameters must not be a different JSON type from one with some."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "operationId": "deleteTransportRulesId",
                "summary": "Delete a transport rule",
                "tags": [
                    "Transport rules"
                ],
                "x-required-scope": "transport_rules:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "The id identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. The rule is gone; a 200 is the whole answer."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/transport-rules/reorder": {
            "put": {
                "operationId": "putTransportRulesReorder",
                "summary": "Reorder (transport rule)",
                "tags": [
                    "Transport rules"
                ],
                "x-required-scope": "transport_rules:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "null",
                                                    "description": "No content. Re-read GET /transport-rules to see the new `priority` values, which are rewritten in steps of 10."
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/transport-rules/{id}/enable": {
            "put": {
                "operationId": "putTransportRulesIdEnable",
                "summary": "Enable a transport rule",
                "tags": [
                    "Transport rules"
                ],
                "x-required-scope": "transport_rules:write",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "The id identifier.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "transport_rule"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "ULID, issued by the mail server. These arrive UPPERCASE (`01M2RV5CEM4MT97RQ00ANRRFCP`) while every Laravel-issued id in the product is lowercase. Both are valid Crockford base32; compare them exactly rather than case-insensitively, because we do not normalise an id we have already issued. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "name": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The rule's display name, required on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "description": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "Free text about the rule. NULL MEANS NONE -- the rule genuinely has no description -- and this is the ONE field on a transport rule where that is what null means. Upstream declares it `description: str | None`, the only optional field on the response model, and `null` round-trips through create unchanged. Everything else nullable on this object is a null we could not read; see `id`."
                                                        },
                                                        "direction": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "enum": [
                                                                "inbound",
                                                                "outbound",
                                                                "both"
                                                            ],
                                                            "description": "Which mail the rule is evaluated against. Defaults to `both` on create, so null is never \"unset\". NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "enabled": {
                                                            "type": "boolean",
                                                            "description": "A disabled rule keeps its priority and is not evaluated."
                                                        },
                                                        "priority": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "LOWER RUNS FIRST. `PUT /transport-rules/reorder` rewrites these in steps of 10 so a rule can be inserted between two others without renumbering the set. Defaults to 100 on create, so null is never \"no priority\" and must not be sorted as 0, which would run the rule FIRST. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it."
                                                        },
                                                        "match": {
                                                            "type": "object",
                                                            "description": "How a message is matched. Was two top-level fields, `condition_logic` and `conditions`, with the prefix doing the grouping; grouped so you can hand the whole matcher to whatever evaluates it.",
                                                            "properties": {
                                                                "logic": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "enum": [
                                                                        "all",
                                                                        "any"
                                                                    ],
                                                                    "description": "`all` requires every condition, `any` requires one. Defaults to `all` on create. NULL MEANS UNKNOWN, never \"this rule has none\": the mail server's `TransportRuleResponse` declares this field REQUIRED and FastAPI validates the response against that model, so a 2xx body cannot omit it. It is published nullable because the shape is defined in another repository and we read it defensively rather than assume it -- a null means we did not get a readable rule back, not that we got a rule without one. Do not substitute a default; treat the rule as unreadable and report it. In particular do NOT read a null as `any`: that would widen a rule from \"every condition\" to \"any condition\" and apply its actions to mail it was never meant to touch."
                                                                },
                                                                "conditions": {
                                                                    "type": "array",
                                                                    "description": "Key order is fixed at `field`, `operator`, `value`. Upstream returns `{field, value, operator}` on read and accepts `{field, operator, value}` on write, so the same rule changed shape round-tripping through this API without changing meaning.",
                                                                    "items": {
                                                                        "type": "object",
                                                                        "properties": {
                                                                            "field": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "enum": [
                                                                                    "sender",
                                                                                    "recipient",
                                                                                    "subject",
                                                                                    "header",
                                                                                    "size",
                                                                                    "has_attachment"
                                                                                ],
                                                                                "description": "What is examined. `size` is the message size in bytes; `has_attachment` is a boolean test. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            },
                                                                            "operator": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "enum": [
                                                                                    "equals",
                                                                                    "contains",
                                                                                    "starts_with",
                                                                                    "ends_with",
                                                                                    "regex",
                                                                                    "greater_than",
                                                                                    "less_than"
                                                                                ],
                                                                                "description": "How `value` is compared against `field`. NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            },
                                                                            "value": {
                                                                                "type": "string",
                                                                                "nullable": true,
                                                                                "description": "What to compare against. ALWAYS A STRING, including for the numeric operators: a `size greater_than` condition reads back as `\"1048576\"`, quoted, because both our request rules (`conditions.*.value` => `required|string`) and upstream's `TransportRuleCondition.value: str` type it that way, and the column stores what they accepted. Parse it yourself for `greater_than` / `less_than`. (Published untyped until phase 3; a caller reading the old description would have expected a number here and got a numeric string.) NULL MEANS UNKNOWN -- the stored condition carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `conditions` as a bare `list[dict]` on its response model, so the `transport_rules.conditions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the condition as uninterpretable rather than guessing at it."
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "actions": {
                                                            "type": "array",
                                                            "description": "What happens to a matched message, in order.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "type": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "enum": [
                                                                            "add_header",
                                                                            "modify_subject",
                                                                            "redirect",
                                                                            "bcc",
                                                                            "reject",
                                                                            "add_disclaimer",
                                                                            "quarantine"
                                                                        ],
                                                                        "description": "What is done to a matched message. NULL MEANS UNKNOWN -- the stored action carried no such key -- and never that it is unset, empty or \"match anything\". Unlike the rest of this object, this value is NOT validated on the way out: the mail server types `actions` as a bare `list[dict]` on its response model, so the `transport_rules.actions` JSON column is published exactly as stored. A rule created through this API cannot produce it (our request rules and upstream's own model both require the key), but a row written any other way is forwarded unexamined. Treat the action as uninterpretable rather than guessing at it. A null is NOT \"do nothing\": the enforcer reads the same column, so an action you cannot name is one you cannot rule out either."
                                                                    },
                                                                    "params": {
                                                                        "type": "object",
                                                                        "additionalProperties": true,
                                                                        "description": "The action's parameters, keyed by name. ALWAYS an object: it was a PHP array, so it serialised as `[]` when empty and `{}` otherwise, and an action with no parameters must not be a different JSON type from one with some."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "ISO 8601 UTC. Upstream sends `\"2026-09-17T23:27:53\"` -- MySQL NOW() through Python's datetime.isoformat(), with no offset and no Z, so a caller could not tell the timezone; it is UTC and is re-emitted as such. NULL MEANS UNKNOWN, never that the rule has no such instant -- every rule was created and every rule was last written. Upstream declares the field REQUIRED (`created_at: str`) and then substitutes an EMPTY STRING when the column is missing, which is neither a timestamp nor a null and would parse as \"now\" if taken at face value; that empty string is what becomes null here. So a null says the mail server had no value to give us, and the rule is older or stranger than its timestamps suggest -- do not order or age rules on a null."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/api-keys": {
            "get": {
                "operationId": "getApiKeys",
                "summary": "List API keys",
                "tags": [
                    "Account"
                ],
                "x-required-scope": "account:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "object": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "api_key"
                                                                ]
                                                            },
                                                            "id": {
                                                                "type": "string",
                                                                "description": "Unique identifier for the key."
                                                            },
                                                            "name": {
                                                                "type": "string",
                                                                "description": "Your label for it. Never null: `api_keys.name` is NOT NULL and `POST /api-keys` requires it, so every response that carries a key carries a name."
                                                            },
                                                            "prefix": {
                                                                "type": "string",
                                                                "description": "`mk_live_` followed by 8 characters. This is the public lookup identifier, **not secret material**: the 32 secret characters follow it and are stored only as a hash. It is what lets you tell two of your own keys apart in an audit log, and it is safe to log. Never null: the column is NOT NULL and unique, because authentication looks the row up by it. A prefix beginning `mk_dead_` instead is a pre-2026-09-17 key that never authenticated anything and has been revoked -- see `revoked_reason`."
                                                            },
                                                            "scopes": {
                                                                "type": "array",
                                                                "items": {
                                                                    "$ref": "#/components/schemas/Scope"
                                                                },
                                                                "description": "The permissions this key grants, as the flat `resource:action` strings the authoriser checks. **An empty list grants nothing** -- it is not a wildcard. Scopes cannot be changed after a key is minted; create a new key."
                                                            },
                                                            "mode": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "live",
                                                                    "test"
                                                                ],
                                                                "description": "A `test` key validates a send exactly as a live one would \u2014 verified sender, suppression check, rate limit \u2014 and then delivers nothing and records nothing. Use one in CI. Test mode is a property of the key rather than a request parameter, so it cannot be switched on by a stray flag in production code, and a live key has no way to express it."
                                                            },
                                                            "state": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "active",
                                                                    "expired",
                                                                    "revoked"
                                                                ],
                                                                "description": "The one lifecycle answer, and **expiry beats the stored status**: authentication refuses an expired key whatever its status column says, so a key reported `active` past its expiry would be a key every request is rejecting. Only `active` authenticates."
                                                            },
                                                            "revoked_reason": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "Why we revoked it, when we did rather than you. **null means NONE was recorded** -- either the key is not revoked at all, or you revoked it yourself, which the API does not annotate. It is never \"we could not read the reason\", so null must not be shown as a revoked key with an unexplained cause: read `state` to learn whether it is revoked and this only to learn why WE did it. A key that silently stops working reads as a breach; one that says `legacy_never_functional` reads as what it is."
                                                            },
                                                            "ip_allowlist": {
                                                                "type": "object",
                                                                "description": "Enforced at authentication time. `enabled: false` with a populated list is a configured allowlist that is currently off, not a contradiction.",
                                                                "properties": {
                                                                    "enabled": {
                                                                        "type": "boolean"
                                                                    },
                                                                    "addresses": {
                                                                        "type": "array",
                                                                        "items": {
                                                                            "type": "string"
                                                                        },
                                                                        "description": "IPv4/IPv6 addresses or CIDR ranges."
                                                                    }
                                                                }
                                                            },
                                                            "last_used": {
                                                                "type": "object",
                                                                "description": "Grouped because both halves carry the same caveat: **the timestamp is throttled to at most one write a minute**, so a key used two seconds ago can report a time up to a minute behind. That is deliberate -- a key serving a thousand requests a minute costs one row update rather than a thousand. Good enough for \"is this key still in use\"; it is not a request log, which is what the events endpoints are for.",
                                                                "properties": {
                                                                    "at": {
                                                                        "type": "string",
                                                                        "format": "date-time",
                                                                        "nullable": true,
                                                                        "description": "ISO 8601 UTC. **null means the key has never been used**, since it was minted -- NONE, not \"not used recently\" and never \"we could not tell\". Usage is written by the authenticating middleware on every accepted request, so a null here is a positive statement that no request has ever authenticated with this key. May be up to a minute stale, as above, which is the one thing it will not tell you precisely."
                                                                    },
                                                                    "ip": {
                                                                        "type": "string",
                                                                        "nullable": true,
                                                                        "description": "The address of the request that last actually recorded usage -- because of the throttle, not necessarily the most recent request. **null alongside a null `at` means the key has never been used** (NONE). null alongside a non-null `at` is the other kind of null: the key WAS used and the address could not be determined for that request, so read it as unknown and not as \"used from nowhere\". This is how you spot a leaked key being used from somewhere you do not recognise."
                                                                    }
                                                                }
                                                            },
                                                            "expires_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "nullable": true,
                                                                "description": "ISO 8601 UTC. **null means the key does not expire** -- NONE, there is no expiry set, and it is optional at creation. **Do not treat null as \"expired\" or as \"unknown\"**: a client that sorts or filters on this and reads a null as a past date will hide or disable a key that works perfectly. Expiry is the one thing that overrides the stored status, so `state` already accounts for it -- read `state` to decide whether a key authenticates, and this only to show or renew the date."
                                                            },
                                                            "created_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "description": "ISO 8601 UTC."
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "The keys your organization holds, with their prefixes, scopes and last use.\n\nListing is available to a key; **creating and revoking are not.** A leaked key that\ncould mint its own replacement would outlive the revocation of the key that leaked,\nso those stay in the dashboard on purpose."
            }
        },
        "/api/v1/billing/usage": {
            "get": {
                "operationId": "getBillingUsage",
                "summary": "Get current usage",
                "tags": [
                    "Account"
                ],
                "x-required-scope": "account:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "usage"
                                                            ]
                                                        },
                                                        "mailboxes": {
                                                            "type": "object",
                                                            "properties": {
                                                                "free_used": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Free-tier mailboxes in use. Counted locally with a SQL count, so a number here is always a real count and an organization with none reads `0`. **null means UNKNOWN \u2014 the count was not supplied**, never zero."
                                                                },
                                                                "free_limit": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "How many free-tier mailboxes are allowed. **null means NO LIMIT, not unknown** \u2014 an organization holding paid seats genuinely has no ceiling on free mailboxes. This is a limit, computed from the catalogue on our side, so it is never unreadable and the two meanings of null cannot collide here."
                                                                },
                                                                "seats": {
                                                                    "type": "object",
                                                                    "description": "Paid seats, per tier.",
                                                                    "properties": {
                                                                        "standard": {
                                                                            "type": "object",
                                                                            "description": "Seats of the standard tier. Counted from the catalogue on our side, so neither figure goes null when the mail server is unreachable.",
                                                                            "properties": {
                                                                                "owned": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Seats bought at this tier. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It never means zero: a tier with no seats reads `0`, and this resource refuses to cast a missing figure to 0 because a fabricated zero reads as a downgrade the customer never made."
                                                                                },
                                                                                "assigned": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Seats in use. CAN EXCEED `owned` after a downgrade \u2014 the two facts are published rather than a single \"available\" figure, whose max(0, \u2026) hid exactly that case. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It never means zero: a tier with no seats reads `0`, and this resource refuses to cast a missing figure to 0 because a fabricated zero reads as a downgrade the customer never made."
                                                                                }
                                                                            }
                                                                        },
                                                                        "pro": {
                                                                            "type": "object",
                                                                            "description": "Seats of the pro tier. Counted from the catalogue on our side, so neither figure goes null when the mail server is unreachable.",
                                                                            "properties": {
                                                                                "owned": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Seats bought at this tier. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It never means zero: a tier with no seats reads `0`, and this resource refuses to cast a missing figure to 0 because a fabricated zero reads as a downgrade the customer never made."
                                                                                },
                                                                                "assigned": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Seats in use. CAN EXCEED `owned` after a downgrade \u2014 the two facts are published rather than a single \"available\" figure, whose max(0, \u2026) hid exactly that case. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It never means zero: a tier with no seats reads `0`, and this resource refuses to cast a missing figure to 0 because a fabricated zero reads as a downgrade the customer never made."
                                                                                }
                                                                            }
                                                                        },
                                                                        "workplace": {
                                                                            "type": "object",
                                                                            "description": "Seats of the workplace tier. Counted from the catalogue on our side, so neither figure goes null when the mail server is unreachable.",
                                                                            "properties": {
                                                                                "owned": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Seats bought at this tier. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It never means zero: a tier with no seats reads `0`, and this resource refuses to cast a missing figure to 0 because a fabricated zero reads as a downgrade the customer never made."
                                                                                },
                                                                                "assigned": {
                                                                                    "type": "integer",
                                                                                    "nullable": true,
                                                                                    "description": "Seats in use. CAN EXCEED `owned` after a downgrade \u2014 the two facts are published rather than a single \"available\" figure, whose max(0, \u2026) hid exactly that case. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It never means zero: a tier with no seats reads `0`, and this resource refuses to cast a missing figure to 0 because a fabricated zero reads as a downgrade the customer never made."
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "send_credits": {
                                                            "type": "object",
                                                            "properties": {
                                                                "balance": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Send credits remaining \u2014 a COUNT OF EMAILS, not money. Read `source` to know which side answered. An exhausted balance reads `0`. **null means UNKNOWN \u2014 neither side produced a figure.** Note this field does NOT go null merely because the mail server is unreachable, unlike the meters around it: the ledger answers in that case and `source` says `ledger`."
                                                                },
                                                                "source": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "enforcer",
                                                                        "ledger"
                                                                    ],
                                                                    "description": "Which side produced `balance`. `enforcer` is the mail server's live counter. `ledger` is our accounting copy, returned when the mail server could not be reached \u2014 both are real numbers, which is why this one does not go null, but they are measured at different moments. SMTP-relay sends create no rows on our side, so the ledger can trail reality by up to fifteen minutes: `ledger` is a signal that the figure may be STALE, not that it is wrong."
                                                                },
                                                                "used_this_month": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Credits consumed this calendar month. **null means UNKNOWN \u2014 the mail server could not be reached.** Never read it as zero; retry instead."
                                                                }
                                                            }
                                                        },
                                                        "app_send": {
                                                            "type": "object",
                                                            "description": "Sending through the API and webmail, as opposed to SMTP relay. EVERY METER IN THIS OBJECT GOES NULL TOGETHER when the mail server is unreachable, so a caller can never see a half-read meter. Three cases to tell apart: `used: 4, included: 400` (sent 4 of 400), `used: 0, included: 400` (sent nothing), and `used: null, included: null` (we could not read the meter \u2014 a transient on our side; retry rather than conclude anything about the customer).",
                                                            "properties": {
                                                                "monthly": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "included": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Emails a month included. Computed from the catalogue here, so an unreachable mail server cannot make it unknown and it does NOT go null with the meter beside it. An organization with no monthly allowance reads `0`. **null means UNKNOWN \u2014 the figure was not supplied**, never zero."
                                                                        },
                                                                        "used": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Emails sent this month. **null means UNKNOWN \u2014 the mail server could not be reached**, never zero."
                                                                        }
                                                                    }
                                                                },
                                                                "daily": {
                                                                    "type": "object",
                                                                    "properties": {
                                                                        "included": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "The daily allowance ACTUALLY IN FORCE at the mail server today \u2014 **not the free floor in the price list**. Those are different numbers. The floor is granted only to an organization with no credit balance and no Send-plan volume, so an account holding either reads `0` here AND THAT 0 IS CORRECT: it is not an outage and not a bug. If you are comparing this against a figure on our pricing page and they differ, this field is the one that governs what you may send. Publishing the catalogue number instead would tell a paying customer they have free sends stacked on what they bought. **null means UNKNOWN \u2014 the mail server could not be reached.**"
                                                                        },
                                                                        "used": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Emails sent today. **null means UNKNOWN \u2014 the mail server could not be reached**, never zero."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "What your organization has sent this period, against its plan allowance and any purchased credits."
            }
        },
        "/api/v1/billing/entitlements": {
            "get": {
                "operationId": "getBillingEntitlements",
                "summary": "Entitlements (billing)",
                "tags": [
                    "Account"
                ],
                "x-required-scope": "account:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "entitlements"
                                                            ]
                                                        },
                                                        "plan": {
                                                            "type": "object",
                                                            "description": "What has been bought. Replaces four rival booleans (`has_subscription`, `has_paid_seats`, `has_paid_product`, `has_send_plan`) that answered one question from four angles and gave a caller four chances to read the wrong one.",
                                                            "properties": {
                                                                "tier": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "free",
                                                                        "paid"
                                                                    ],
                                                                    "nullable": true,
                                                                    "description": "The honest summary of whether anything has been bought. It is also what the mail server holds this organization's bounce tripwires to. `free` and `paid` are the whole set and EVERY organization has one: an organization that has bought nothing reads `free`, not null. So **null means UNKNOWN \u2014 the entitlement snapshot did not carry the field** \u2014 and must not be read as \"no plan\". \"No plan\" is `tier: \"free\"` with `status: null` beside it, and those two together are the answer `has_subscription` and three other booleans used to give four ways."
                                                                },
                                                                "status": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "active",
                                                                        "past_due",
                                                                        "suspended",
                                                                        "cancelled"
                                                                    ],
                                                                    "nullable": true,
                                                                    "description": "**null means NONE \u2014 there is no subscription at all.** It is the one flag that replaced `has_subscription`, an answer rather than a missing value, and it is why four rival booleans could be dropped."
                                                                }
                                                            }
                                                        },
                                                        "seats": {
                                                            "type": "object",
                                                            "description": "Paid seats bought and in use, per tier. What a null on any leaf below means is stated ON THAT LEAF \u2014 this heading does not reach the field you are indexing into, and a caller reads the field it is using.",
                                                            "properties": {
                                                                "standard": {
                                                                    "type": "object",
                                                                    "description": "Seats of the standard tier. Both figures come from the entitlement snapshot, which counts them locally.",
                                                                    "properties": {
                                                                        "owned": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Seats bought at this tier. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        },
                                                                        "assigned": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Seats in use. Can exceed `owned` after a downgrade. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        }
                                                                    }
                                                                },
                                                                "pro": {
                                                                    "type": "object",
                                                                    "description": "Seats of the pro tier. Both figures come from the entitlement snapshot, which counts them locally.",
                                                                    "properties": {
                                                                        "owned": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Seats bought at this tier. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        },
                                                                        "assigned": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Seats in use. Can exceed `owned` after a downgrade. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        }
                                                                    }
                                                                },
                                                                "workplace": {
                                                                    "type": "object",
                                                                    "description": "Seats of the workplace tier. Both figures come from the entitlement snapshot, which counts them locally.",
                                                                    "properties": {
                                                                        "owned": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Seats bought at this tier. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        },
                                                                        "assigned": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Seats in use. Can exceed `owned` after a downgrade. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "mailbox_tiers": {
                                                            "type": "object",
                                                            "description": "What each tier grants one mailbox, free included, so a caller sizing an integration can see what the tier they are about to buy gives. NULL DOES NOT MEAN THE SAME THING ON ALL THREE FIELDS: on `daily_send_limit` it means NO LIMIT, a real entitlement; on `storage_bytes` and `assistant_actions` it means UNKNOWN, because those are finite grants and an unlimited reading would be an invention. Each leaf says which \u2014 read the leaf, not this heading.",
                                                            "properties": {
                                                                "free": {
                                                                    "type": "object",
                                                                    "description": "What the free tier grants ONE mailbox.",
                                                                    "properties": {
                                                                        "storage_bytes": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Bytes \u2014 the same unit as every other size in the API, never GB. **null means UNKNOWN \u2014 the catalogue figure was not readable.** Unlike `daily_send_limit` below it, this one has no \"no limit\" reading: every tier has a finite mailbox quota, so a null here is a gap in what we were given rather than an unlimited allowance."
                                                                        },
                                                                        "daily_send_limit": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Emails one mailbox of this tier may send per day. **null means NO LIMIT, not unknown.** A `0` is never published here: the stored column uses 0 for \"uncapped\" (the rate limiter enforces only on `daily_limit > 0`), and publishing that 0 verbatim would tell a caller their most expensive tier may send nothing at all. Any new-account clamp is already applied to this number, so what you see is what binds."
                                                                        },
                                                                        "assistant_actions": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Assistant actions granted per mailbox, per month. A tier that grants none reads `0`, and THAT `0` MEANS NONE \u2014 not \"uncapped\", which is what a 0 means two lines above in `daily_send_limit`. The two conventions sit in one object, so read each field's own note. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        }
                                                                    }
                                                                },
                                                                "standard": {
                                                                    "type": "object",
                                                                    "description": "What the standard tier grants ONE mailbox.",
                                                                    "properties": {
                                                                        "storage_bytes": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Bytes \u2014 the same unit as every other size in the API, never GB. **null means UNKNOWN \u2014 the catalogue figure was not readable.** Unlike `daily_send_limit` below it, this one has no \"no limit\" reading: every tier has a finite mailbox quota, so a null here is a gap in what we were given rather than an unlimited allowance."
                                                                        },
                                                                        "daily_send_limit": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Emails one mailbox of this tier may send per day. **null means NO LIMIT, not unknown.** A `0` is never published here: the stored column uses 0 for \"uncapped\" (the rate limiter enforces only on `daily_limit > 0`), and publishing that 0 verbatim would tell a caller their most expensive tier may send nothing at all. Any new-account clamp is already applied to this number, so what you see is what binds."
                                                                        },
                                                                        "assistant_actions": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Assistant actions granted per mailbox, per month. A tier that grants none reads `0`, and THAT `0` MEANS NONE \u2014 not \"uncapped\", which is what a 0 means two lines above in `daily_send_limit`. The two conventions sit in one object, so read each field's own note. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        }
                                                                    }
                                                                },
                                                                "pro": {
                                                                    "type": "object",
                                                                    "description": "What the pro tier grants ONE mailbox.",
                                                                    "properties": {
                                                                        "storage_bytes": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Bytes \u2014 the same unit as every other size in the API, never GB. **null means UNKNOWN \u2014 the catalogue figure was not readable.** Unlike `daily_send_limit` below it, this one has no \"no limit\" reading: every tier has a finite mailbox quota, so a null here is a gap in what we were given rather than an unlimited allowance."
                                                                        },
                                                                        "daily_send_limit": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Emails one mailbox of this tier may send per day. **null means NO LIMIT, not unknown.** A `0` is never published here: the stored column uses 0 for \"uncapped\" (the rate limiter enforces only on `daily_limit > 0`), and publishing that 0 verbatim would tell a caller their most expensive tier may send nothing at all. Any new-account clamp is already applied to this number, so what you see is what binds."
                                                                        },
                                                                        "assistant_actions": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Assistant actions granted per mailbox, per month. A tier that grants none reads `0`, and THAT `0` MEANS NONE \u2014 not \"uncapped\", which is what a 0 means two lines above in `daily_send_limit`. The two conventions sit in one object, so read each field's own note. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        }
                                                                    }
                                                                },
                                                                "workplace": {
                                                                    "type": "object",
                                                                    "description": "What the workplace tier grants ONE mailbox.",
                                                                    "properties": {
                                                                        "storage_bytes": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Bytes \u2014 the same unit as every other size in the API, never GB. **null means UNKNOWN \u2014 the catalogue figure was not readable.** Unlike `daily_send_limit` below it, this one has no \"no limit\" reading: every tier has a finite mailbox quota, so a null here is a gap in what we were given rather than an unlimited allowance."
                                                                        },
                                                                        "daily_send_limit": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Emails one mailbox of this tier may send per day. **null means NO LIMIT, not unknown.** A `0` is never published here: the stored column uses 0 for \"uncapped\" (the rate limiter enforces only on `daily_limit > 0`), and publishing that 0 verbatim would tell a caller their most expensive tier may send nothing at all. Any new-account clamp is already applied to this number, so what you see is what binds."
                                                                        },
                                                                        "assistant_actions": {
                                                                            "type": "integer",
                                                                            "nullable": true,
                                                                            "description": "Assistant actions granted per mailbox, per month. A tier that grants none reads `0`, and THAT `0` MEANS NONE \u2014 not \"uncapped\", which is what a 0 means two lines above in `daily_send_limit`. The two conventions sit in one object, so read each field's own note. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "limits": {
                                                            "type": "object",
                                                            "description": "Account-wide ceilings. **null means NO LIMIT, not unknown** \u2014 that is precisely what the entitlement returns for a paying organization, and this publishes its meaning rather than flattening it to a number.",
                                                            "properties": {
                                                                "max_mailboxes": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Mailboxes this organization may hold in total. **null means NO LIMIT, not unknown.**"
                                                                },
                                                                "max_domains": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Domains this organization may add. **null means NO LIMIT, not unknown.**"
                                                                },
                                                                "max_aliases_per_mailbox": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Aliases each mailbox may have. **null means NO LIMIT, not unknown.**"
                                                                },
                                                                "max_team_members": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "People who may be invited to the organization. **null means NO LIMIT, not unknown.**"
                                                                }
                                                            }
                                                        },
                                                        "allowances": {
                                                            "type": "object",
                                                            "properties": {
                                                                "app_send_monthly": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Emails a month from a Send plan plus any seats held. Computed from the catalogue, never fetched, so an unreachable mail server cannot make it unknown. An organization holding no monthly volume reads `0`. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed. There is deliberately NO daily figure on this endpoint: what is enforced daily is published once, by `GET /billing/usage`."
                                                                },
                                                                "send_credit_balance": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "The LEDGER balance of send credits \u2014 a count of emails, not money. This is the accounting figure; a caller deciding whether it can send right now should read `GET /billing/usage`, which publishes the enforcer's live counter and says which source answered. An account that holds no credits reads `0`. **null means UNKNOWN \u2014 the entitlement snapshot did not carry this figure.** It is never zero: an organization with none of this reads `0`, and this resource refuses to cast a missing figure to 0 rather than publish a number nobody computed."
                                                                }
                                                            }
                                                        },
                                                        "features": {
                                                            "type": "object",
                                                            "description": "Feature entitlements. Whether a feature is GRANTED, not whether it is configured.",
                                                            "properties": {
                                                                "branded_webmail": {
                                                                    "type": "boolean"
                                                                },
                                                                "priority_support": {
                                                                    "type": "boolean"
                                                                },
                                                                "dedicated_ip": {
                                                                    "type": "boolean",
                                                                    "description": "Whether a dedicated IP may be requested. Its state is at `GET /dedicated-ip`."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/billing/subscription": {
            "get": {
                "operationId": "getBillingSubscription",
                "summary": "Subscription (billing)",
                "tags": [
                    "Account"
                ],
                "x-required-scope": "account:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The subscription this organization holds, or `null` (with HTTP 200) for an organization that has never subscribed \u2014 an empty state, not an error. NO PAYMENT PROVIDER IS NAMED anywhere in this object, and no provider-side customer or subscription reference appears. Which rail we settle on is our arrangement and it changes without the customer's involvement.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "subscription"
                                                            ]
                                                        },
                                                        "id": {
                                                            "type": "string",
                                                            "description": "Unique identifier for the subscription."
                                                        },
                                                        "status": {
                                                            "type": "string",
                                                            "enum": [
                                                                "pending",
                                                                "active",
                                                                "past_due",
                                                                "suspended",
                                                                "cancelled"
                                                            ],
                                                            "description": "The one lifecycle answer, and the actionable half of our collections process: `past_due` means a payment failed, `suspended` means sending has stopped. How many times we have retried a card, and when data would be purged, are internal and deliberately not published."
                                                        },
                                                        "currency": {
                                                            "type": "string",
                                                            "description": "ISO 4217 code, e.g. `NGN` or `USD`. THE CURRENCY THE CUSTOMER AGREED \u2014 nothing here is converted. Every amount below is in this currency's minor unit."
                                                        },
                                                        "interval": {
                                                            "type": "string",
                                                            "enum": [
                                                                "month",
                                                                "year"
                                                            ],
                                                            "description": "The billing period. (One-off prices exist for credit packs, which are bought outright and never appear on a subscription.)"
                                                        },
                                                        "items": {
                                                            "type": "array",
                                                            "description": "Line by line \u2014 what lets a caller see \"3 Standard, 4 Pro\" rather than one plan name that would be a lie about what is held.",
                                                            "items": {
                                                                "type": "object",
                                                                "properties": {
                                                                    "product_key": {
                                                                        "type": "string",
                                                                        "description": "The stable catalogue key, and the ONLY catalogue identifier published \u2014 it is the handle you pass to `POST /billing/subscription/items` to change quantity. Internal product and price row ids are not published."
                                                                    },
                                                                    "tier": {
                                                                        "type": "string",
                                                                        "enum": [
                                                                            "standard",
                                                                            "pro",
                                                                            "workplace"
                                                                        ],
                                                                        "nullable": true,
                                                                        "description": "The mailbox tier this line buys seats of. **null means NONE \u2014 this line is not a seat product** (a Send plan or an add-on), not that its tier is unknown. `product_key` identifies it in every case."
                                                                    },
                                                                    "quantity": {
                                                                        "type": "integer",
                                                                        "description": "How many of this product."
                                                                    },
                                                                    "unit_amount": {
                                                                        "type": "integer",
                                                                        "description": "Price of ONE unit per `interval`. Integer in the MINOR UNITS of `currency` \u2014 kobo when `currency` is `NGN`, cents when it is `USD`. Never a major-unit or decimal value: `150000` under `NGN` is \u20a61,500.00, not \u20a6150,000. Divide by the currency's minor-unit exponent (100 for both NGN and USD) only at the point of display. This is the price locked to this line, so it can differ from today's list price."
                                                                    },
                                                                    "subtotal": {
                                                                        "type": "integer",
                                                                        "description": "`quantity` x `unit_amount`, computed once so it cannot drift from the line it describes. Integer in the MINOR UNITS of `currency` \u2014 kobo when `currency` is `NGN`, cents when it is `USD`. Never a major-unit or decimal value: `150000` under `NGN` is \u20a61,500.00, not \u20a6150,000. Divide by the currency's minor-unit exponent (100 for both NGN and USD) only at the point of display."
                                                                    }
                                                                }
                                                            }
                                                        },
                                                        "total": {
                                                            "type": "integer",
                                                            "description": "The sum of every line's `subtotal` for one `interval`. Integer in the MINOR UNITS of `currency` \u2014 kobo when `currency` is `NGN`, cents when it is `USD`. Never a major-unit or decimal value: `150000` under `NGN` is \u20a61,500.00, not \u20a6150,000. Divide by the currency's minor-unit exponent (100 for both NGN and USD) only at the point of display. Taxes and any payment fees are not included."
                                                        },
                                                        "current_period_start": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the current billing period began. **null means NONE \u2014 there is no period yet.** A subscription is created `pending` with no period at all, and a period is stamped only when the first successful payment activates it. So a null here is a fact about the subscription, not a gap in what we read, and it travels with `status: \"pending\"`."
                                                        },
                                                        "current_period_end": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the current period ends. With `auto_renew` true this is when `total` is charged again. **null means NONE \u2014 no period has started**, so there is no renewal date for `auto_renew` to act on yet. Do not read it as \"does not renew\": read `auto_renew` for that, and `status` for why no period exists."
                                                        },
                                                        "auto_renew": {
                                                            "type": "boolean"
                                                        },
                                                        "cancelled_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When cancellation was requested. **null means NONE \u2014 no cancellation has been requested.** Service continues to `current_period_end` after one is, so a date here does not mean sending has stopped; `status` says that."
                                                        },
                                                        "price_locked_until": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "A promise about price the customer can hold us to: rates on this subscription will not rise before this date. **null means NONE \u2014 no lock applies**, which is the ordinary case: monthly terms buy no lock, annual prepay does."
                                                        },
                                                        "created_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the subscription row was created \u2014 which is when checkout produced it, NOT when it started billing. For that read `current_period_start`, which is stamped on first payment. **null means UNKNOWN \u2014 the stored timestamp was absent**; it is written on insert, so it should always be present."
                                                        },
                                                        "updated_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the subscription last changed. **null means UNKNOWN \u2014 the stored timestamp was absent**, never \"never changed\"."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/billing/send-plan": {
            "get": {
                "operationId": "getBillingSendPlan",
                "summary": "Send Plan (billing)",
                "tags": [
                    "Account"
                ],
                "x-required-scope": "account:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "description": "The Send plan held, this month's overage, and the spend cap. No payment processor is named: which rail would collect an overage charge is our arrangement, not the customer's data.",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "send_plan"
                                                            ]
                                                        },
                                                        "plan_key": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The catalogue key of the plan held. **null means NONE \u2014 this organization is on no Send plan at all**, which is a real and common state rather than a gap in what we read. Plans are mutually exclusive by design, so there is never more than one."
                                                        },
                                                        "currency": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "ISO 4217 code, e.g. `NGN` or `USD`. Every amount below is in this currency's minor unit, unconverted. IT IS ALWAYS POPULATED: it is taken from the live subscription when there is one, and falls back to `NGN` \u2014 the currency the price list is written in \u2014 when there is not. So null does NOT mean \"no plan\" (that is `plan_key`) and does NOT mean \"no overage rate exists\" (that is `overage.rate_per_thousand`): an organization with neither still reads `NGN` here. **null means UNKNOWN \u2014 the currency was not supplied**, and in that case NO amount in this response can be interpreted at all, since every one of them is a count of this currency's minor units. Treat the amounts as unreadable rather than assuming a default."
                                                        },
                                                        "included_monthly": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "Emails a month the plan includes. Computed from the catalogue on our side, so this is the one figure here an unreachable mail server cannot make unknown, and it does not go null with the meters below. An organization on no plan reads `0`. **null means UNKNOWN \u2014 the figure was not supplied**, never zero."
                                                        },
                                                        "used_this_month": {
                                                            "type": "integer",
                                                            "nullable": true,
                                                            "description": "Emails sent this calendar month, per the mail server. **null means UNKNOWN \u2014 the meter could not be read.** It never means zero. Only one of those two says the integration is idle, and treating unknown as zero is how a customer is under-billed silently. Retry rather than conclude anything. THE FOUR FIELDS DERIVED FROM THIS ONE GO NULL WITH IT: `overage.emails`, `overage.amount` and `spend_cap.reached`."
                                                        },
                                                        "overage": {
                                                            "type": "object",
                                                            "description": "Sending past `included_monthly`, and what it costs.",
                                                            "properties": {
                                                                "emails": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Emails past the included volume. **null means UNKNOWN \u2014 the meter this is derived from could not be read at the mail server**, in exactly the cases `used_this_month` is null: a derived number is as unknown as what it came from. Never zero; retry rather than conclude the customer is inside their allowance."
                                                                },
                                                                "amount": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "What the overage costs so far this month. Integer in the MINOR UNITS of `currency` \u2014 kobo when `currency` is `NGN`, cents when it is `USD`. Never a major-unit or decimal value: `150000` under `NGN` is \u20a61,500.00, not \u20a6150,000. **null means UNKNOWN**, whenever `used_this_month` is null. It is NOT a zero bill: a zero here derived from an unread meter is the under-billing this field exists to refuse."
                                                                },
                                                                "rate_per_thousand": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Charged per 1,000 emails past the included volume. Integer in the MINOR UNITS of `currency` \u2014 kobo when `currency` is `NGN`, cents when it is `USD`. Never a major-unit or decimal value: `150000` under `NGN` is \u20a61,500.00, not \u20a6150,000. **null means NONE \u2014 the plan has no overage rate** \u2014 a real setting, not an unread meter. This one comes from the price list, not the mail server, which is why it stays known when the meters do not."
                                                                }
                                                            }
                                                        },
                                                        "spend_cap": {
                                                            "type": "object",
                                                            "description": "An optional ceiling on overage spend for the month.",
                                                            "properties": {
                                                                "amount": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "The cap. Integer in the MINOR UNITS of `currency` \u2014 kobo when `currency` is `NGN`, cents when it is `USD`. Never a major-unit or decimal value: `150000` under `NGN` is \u20a61,500.00, not \u20a6150,000. **null means NONE \u2014 NO CAP is set.** This comes from our own table and is never unreadable. **`0` IS A REAL AND DIFFERENT SETTING**, meaning \"stop at my included volume, never charge me overage\". Do not collapse the two: a cap is cleared by sending null, never by sending zero, and reading a `0` as \"no cap\" would let an account that asked never to be charged run up a bill."
                                                                },
                                                                "reached": {
                                                                    "type": "boolean",
                                                                    "nullable": true,
                                                                    "description": "Whether the cap has been hit. **null means UNKNOWN** \u2014 there is a cap, but the overage it would be compared against rests on a meter the mail server could not give us, so it could not be measured. `false` here is a positive claim that the cap has NOT been reached, and is the more dangerous of the two wrong answers: it would let a client sail past a cap it believed unreached. `false` is also the honest answer when `amount` is null, since no cap can be reached."
                                                                },
                                                                "ceiling_emails": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "The cap expressed in emails \u2014 the only unit the mail server can enforce on the send path, since it counts messages and cannot evaluate a money figure. **null means NONE \u2014 no ceiling**, which follows from `spend_cap.amount` being null; it is derived from the cap and the rate on our side, so it is never unknown."
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v1/dedicated-ip": {
            "get": {
                "operationId": "getDedicatedIp",
                "summary": "Get dedicated IP status",
                "tags": [
                    "Account"
                ],
                "x-required-scope": "account:read",
                "security": [
                    {
                        "ApiKeyAuth": []
                    },
                    {
                        "SessionToken": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Success.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "allOf": [
                                        {
                                            "$ref": "#/components/schemas/Envelope"
                                        },
                                        {
                                            "type": "object",
                                            "properties": {
                                                "data": {
                                                    "type": "object",
                                                    "properties": {
                                                        "object": {
                                                            "type": "string",
                                                            "enum": [
                                                                "dedicated_ip"
                                                            ]
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "enum": [
                                                                "shared",
                                                                "requested",
                                                                "provisioning",
                                                                "warming",
                                                                "live",
                                                                "paused",
                                                                "quarantined"
                                                            ],
                                                            "nullable": true,
                                                            "description": "The one lifecycle answer. `shared` is the default and where an organization that has never asked sits \u2014 it is an empty state, not an error. `requested` applied for, awaiting review; `provisioning` approved and being allocated; `warming` assigned and ramping (`warmup` is non-null); `live` fully warmed and sending at full rate; `paused` sending suspended but the address retained; `quarantined` withdrawn over a reputation problem. EVERY organization has one of these seven \u2014 an organization that has never asked is `shared`, not null \u2014 so **null means UNKNOWN: the state was not supplied**, and nothing else in this object can be read against it. In particular it never means \"no dedicated IP\"; that is `shared`."
                                                        },
                                                        "address": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "The IP address allocated to this organization, once one exists. **null means NONE \u2014 no address has been allocated**, which is the case on the shared pool and while a request is still an application with nothing behind it. It is not a value we failed to read: the address is mirrored onto the organization here, so it is as readable as any other column."
                                                        },
                                                        "spf_include": {
                                                            "type": "string",
                                                            "nullable": true,
                                                            "description": "What to add to your own SPF record to authorize this address, e.g. `include:spf.your-slug.example`. Minted for your organization and meaningless outside your DNS \u2014 it names no mail server of ours. **null means NONE \u2014 there is no address to authorize yet**, and it is derived from `address` rather than stored, so it is null exactly when that is. Naming a host before it exists would invite you to publish a reference to nothing."
                                                        },
                                                        "requested_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When a dedicated IP was applied for. **null means NONE \u2014 no application has ever been made**, which is where an organization on the shared pool sits."
                                                        },
                                                        "live_at": {
                                                            "type": "string",
                                                            "format": "date-time",
                                                            "nullable": true,
                                                            "description": "When the address finished warming and began sending at full rate. **null means NONE \u2014 it has not gone live**, whether because it is still warming, still being provisioned, or was never requested. Read `state` for which. It is never a date we could not read."
                                                        },
                                                        "warmup": {
                                                            "type": "object",
                                                            "nullable": true,
                                                            "description": "The ramp, while it is running. **THIS IS THE ONE FIELD IN THIS RESPONSE WHOSE NULL CARRIES TWO MEANINGS, and we cannot tell you which from this field alone.** Usually it is NONE: an address that is `live` has no warm-up left, and one not yet allocated has no ramp to describe. But it is also null when the warm-up ceiling could not be read, which is UNKNOWN. Resolve it with `state`: a null `warmup` while `state` is `warming` means the figures were unavailable \u2014 retry \u2014 and a null in any other state means there is genuinely no ramp. The service returns one null for both cases; fixing that means changing what it returns, so it is documented here rather than papered over.",
                                                            "properties": {
                                                                "day": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Which day of the warm-up schedule this is. Always populated inside a non-null `warmup`. **null means UNKNOWN \u2014 the figure was not supplied**, never day zero."
                                                                },
                                                                "daily_limit": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "RECIPIENTS this address may take today. A limit, named like every other limit in the API \u2014 but NOT one whose null means \"no limit\": a warm-up always has a ceiling, and when that ceiling cannot be read the WHOLE `warmup` object is null rather than this field. So inside a non-null `warmup` this is always populated, and **null means UNKNOWN \u2014 the ceiling was not supplied.** Reading it as \"uncapped\" would let a client send at full rate through a ramp, which is the one thing a warm-up exists to prevent."
                                                                },
                                                                "sent_today": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Recipients this address has taken today, counted from our own send history. Nothing sent reads `0`. **null means UNKNOWN \u2014 the count was not supplied**, never zero."
                                                                },
                                                                "remaining": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "`daily_limit` minus `sent_today`, floored at zero. **null means UNKNOWN**, in exactly the cases the two figures it is derived from are \u2014 a derived number is as unknown as what it came from. A ramp with nothing left reads `0`."
                                                                },
                                                                "completes_on": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the ramp is scheduled to finish, on the current schedule. Projected from the date the warm-up started, so **null means UNKNOWN \u2014 that start date was missing or unreadable, and the finish could not be projected.** This one is genuinely reachable. It never means the ramp does not finish: you only see this object while `state` is `warming`, and a ramp that has finished has no `warmup` at all."
                                                                }
                                                            }
                                                        },
                                                        "terms": {
                                                            "type": "object",
                                                            "description": "The dedicated-IP addendum, as it stands for this organization.",
                                                            "properties": {
                                                                "version_in_force": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "The addendum version a new request must accept today. A configured value on our side, the same for every organization, so it is always populated. **null means UNKNOWN \u2014 the version was not supplied**; it never means no addendum applies, and an empty string should be read the same way."
                                                                },
                                                                "accepted_version": {
                                                                    "type": "string",
                                                                    "nullable": true,
                                                                    "description": "What this organization actually accepted. Stored verbatim, so it still says which text they read after a deploy has moved `version_in_force` on. **null means NONE \u2014 nothing has been accepted.** Compare it against `version_in_force`: they differ legitimately, and a difference is not an error."
                                                                },
                                                                "accepted_at": {
                                                                    "type": "string",
                                                                    "format": "date-time",
                                                                    "nullable": true,
                                                                    "description": "When the addendum was accepted. **null means NONE \u2014 nothing has been accepted**, and it is null exactly when `accepted_version` is: the two come from the same acceptance record, so they cannot disagree."
                                                                }
                                                            }
                                                        },
                                                        "eligibility": {
                                                            "type": "object",
                                                            "description": "Whether a dedicated IP can be requested, and the figures worth seeing before deciding to.",
                                                            "properties": {
                                                                "can_request": {
                                                                    "type": "boolean",
                                                                    "description": "Whether a request would be accepted right now. Governed by `requirements` alone; everything else in this object is disclosure and never blocks a request."
                                                                },
                                                                "requirements": {
                                                                    "type": "object",
                                                                    "description": "The two HARD requirements. Both must be true for `can_request`.",
                                                                    "properties": {
                                                                        "domain_verified": {
                                                                            "type": "boolean",
                                                                            "description": "At least one domain verified for sending. See `verified_domains` for which."
                                                                        },
                                                                        "marketing_approved": {
                                                                            "type": "boolean"
                                                                        }
                                                                    }
                                                                },
                                                                "verified_domains": {
                                                                    "type": "array",
                                                                    "items": {
                                                                        "type": "string"
                                                                    },
                                                                    "description": "Domain NAMES, not ids \u2014 the list that satisfies `domain_verified`, readable without a second lookup."
                                                                },
                                                                "monthly_volume": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "Emails actually sent over the last 30 days. A genuine `0` when nothing was sent: this is a local sum over our own event aggregates, and an organization that has sent nothing really has sent nothing. **null means UNKNOWN \u2014 the sum was not supplied**, and it is the one reading you must not treat as zero. Contrast `bounce_rate` beside it, where null is the honest answer to having sent nothing."
                                                                },
                                                                "volume_threshold": {
                                                                    "type": "integer",
                                                                    "nullable": true,
                                                                    "description": "The volume at which a dedicated IP starts to pay for itself. Published beside `monthly_volume` in the same unit, with the comparison left to you rather than restated as a second field that could disagree. A configured figure on our side, identical for every organization, so **null means UNKNOWN \u2014 it was not supplied**, never \"no threshold\"."
                                                                },
                                                                "bounce_rate": {
                                                                    "type": "number",
                                                                    "format": "float",
                                                                    "nullable": true,
                                                                    "description": "Percentage of the last 30 days' deliveries that bounced, measured from your own send history. **null means NONE \u2014 there is nothing to rate, because nothing was sent in the window. Never 0.** A rate computed from no deliveries is not a good rate, and buying a dedicated IP on the strength of one would be acting on a number nobody measured. NOTE THIS IS NOT A REPUTATION SCORE and must not be read as one: it is a single measured ratio over a fixed window, with no judgement attached and none implied when it is null."
                                                                }
                                                            }
                                                        },
                                                        "can_return_to_shared": {
                                                            "type": "boolean",
                                                            "description": "Whether this organization may move back to the shared pool, which the addendum permits at any time. It is also how an application is withdrawn."
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Your dedicated sending address and its warm-up state. An organization on a shared IP gets a populated object whose `state` is `shared` and whose `address` is null \u2014 NOT a null result, and never an error. Reachable with an organization API key carrying `account:read`; a key without that scope is refused with 403."
            }
        },
        "/api/v1/mailbox-auth/login": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Sign in to the webmail with mailbox credentials",
                "description": "Exchanges a mailbox's own email and password for a webmail session. The password is verified by IMAP LOGIN against Dovecot, never against a stored copy, so this can never disagree with what a mail client would accept. Unauthenticated by design, rate-limited by IP and by address. Send `X-Client-Platform: ios|android|macos|windows|linux` from a native app to receive the native session lifetimes (default 30 days idle / 180 days absolute) instead of the browser's 8 hours / 7 days. If the account carries a temporary password the session is still issued, `data.must_change_password` is true, and every /api/v1/mailbox/* route except POST /security/password and logout answers 403 `password_change_required` until a new password is set.",
                "operationId": "login_api_v1_mailbox_auth_login_post",
                "parameters": [
                    {
                        "name": "X-Forwarded-For",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "string"
                                },
                                {
                                    "type": "null"
                                }
                            ],
                            "title": "X-Forwarded-For"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/MailboxLoginRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox-auth/logout": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "End the current webmail session",
                "description": "Revokes the session server-side and clears its cookies. Idempotent.",
                "operationId": "logout_api_v1_mailbox_auth_logout_post",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/capabilities": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "What this deployment's webmail can actually do",
                "description": "Runtime feature detection for the webmail: which optional services are configured on THIS deployment. Distinct from /api/v1/capabilities, which reports the build's edition (CE vs Pro) and cannot answer questions like 'is an AI endpoint configured', since two deployments of the same edition differ. The webmail hides any control this does not advertise.",
                "operationId": "capabilities_api_v1_mailbox_capabilities_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/folders": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "List the mailbox's folders",
                "description": "Every folder with its message and unread counts plus IMAP's UIDNEXT and UIDVALIDITY. Polling those two is the webmail's delta check: unchanged tokens mean nothing arrived, moved or was deleted, for one request that transfers no messages.",
                "operationId": "folders_api_v1_mailbox_folders_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Create a folder",
                "description": "Creates and subscribes an IMAP folder. This is also what the webmail's label management calls -- a label IS a folder here, not a separate concept invented in the UI.",
                "operationId": "create_folder_route_api_v1_mailbox_folders_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateFolderRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/folders/{folder}": {
            "patch": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Rename a folder",
                "description": "`folder` is the id GET /folders returns. `name` is the new last segment; a nested folder keeps its parent, and RENAME carries its subfolders along. INBOX and the special-use folders (Sent, Drafts, Junk, Trash, Archive -- detected by SPECIAL-USE attribute and by well-known name) answer 409 `cannot_rename_special_folder`.",
                "operationId": "rename_folder_route_api_v1_mailbox_folders__folder__patch",
                "parameters": [
                    {
                        "name": "folder",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Folder"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/RenameFolderRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Delete an empty folder",
                "description": "`folder` is the id GET /folders returns. Refused with 409 `cannot_delete_special_folder` for INBOX and the special-use folders, and with 409 `folder_not_empty` (messages) or `folder_has_subfolders` while anything is still inside -- IMAP DELETE destroys contents without a Trash step, so the holder empties the folder deliberately first. The client should warn on 409 rather than retry.",
                "operationId": "delete_folder_route_api_v1_mailbox_folders__folder__delete",
                "parameters": [
                    {
                        "name": "folder",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Folder"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "List messages in a folder",
                "description": "Newest first, server-side searched and paged. `q` is resolved by IMAP SEARCH against Dovecot's own indexes -- including message bodies -- so a word buried deep in an email is findable, which a client-side search over preview text can never be.",
                "operationId": "messages_api_v1_mailbox_messages_get",
                "parameters": [
                    {
                        "name": "folder",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "string",
                                    "maxLength": 255
                                },
                                {
                                    "type": "null"
                                }
                            ],
                            "title": "Folder"
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "string",
                                    "maxLength": 255
                                },
                                {
                                    "type": "null"
                                }
                            ],
                            "title": "Search"
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "string",
                                    "maxLength": 255
                                },
                                {
                                    "type": "null"
                                }
                            ],
                            "title": "Q"
                        }
                    },
                    {
                        "name": "unread",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean",
                            "default": false,
                            "title": "Unread"
                        }
                    },
                    {
                        "name": "starred",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean",
                            "default": false,
                            "title": "Starred"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "maximum": 200,
                            "minimum": 1,
                            "default": 50,
                            "title": "Limit"
                        }
                    },
                    {
                        "name": "offset",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 0,
                            "default": 0,
                            "title": "Offset"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/draft": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Save a draft",
                "description": "Appends the draft to the Drafts folder as a real message, so it is readable by every other client on the account rather than living in a webmail-only table.",
                "operationId": "save_draft_api_v1_mailbox_messages_draft_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SaveDraftRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/draft/{message_id}": {
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Discard a draft",
                "description": "Permanently removes a draft. Allowed outside Trash because a draft the author just discarded was never delivered mail.",
                "operationId": "discard_draft_api_v1_mailbox_messages_draft__message_id__delete",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/scheduled": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Messages waiting to be sent",
                "description": "Send times for everything in the Scheduled folder, keyed by the same message id the folder listing returns, so a client merges the two rather than fetching the messages twice. Includes any that FAILED: a scheduled message that did not go out is the one the holder most needs to see.",
                "operationId": "scheduled_messages_api_v1_mailbox_messages_scheduled_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/scheduled/{message_id}": {
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Cancel a scheduled send",
                "description": "Moves the message back to Drafts and forgets the schedule. The message is never destroyed -- someone cancelling a send wants to change it, not lose it.",
                "operationId": "cancel_scheduled_api_v1_mailbox_messages_scheduled__message_id__delete",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Read one message",
                "description": "The full message with both body representations and attachment metadata. Fetched with BODY.PEEK, so opening a message does not mark it read -- the client says so explicitly via /mark-read, which is what makes 'mark as unread' mean anything.",
                "operationId": "message_detail_api_v1_mailbox_messages__message_id__get",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Permanently delete a message",
                "description": "Refused unless the message is ALREADY in Trash. PRD section 7 is binding: nothing outside Trash is ever destroyed, so reaching this requires a deliberate second delete from inside Trash.",
                "operationId": "message_destroy_api_v1_mailbox_messages__message_id__delete",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/attachments": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "List a message's attachments",
                "operationId": "message_attachments_api_v1_mailbox_messages__message_id__attachments_get",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/attachments/{index}": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Download one attachment",
                "description": "Streams the decoded part back with its own content type and filename.",
                "operationId": "message_attachment_api_v1_mailbox_messages__message_id__attachments__index__get",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    },
                    {
                        "name": "index",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "title": "Index"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/raw": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Download the original message (RFC 822)",
                "description": "The stored bytes exactly as Dovecot holds them -- headers, MIME structure and encodings untouched, never a re-serialisation. What 'Show original' and 'Download .eml' load, and the ground truth for any 'is the API dropping this header?' question. Fetched with BODY.PEEK, so it does not mark the message read.",
                "operationId": "message_raw_api_v1_mailbox_messages__message_id__raw_get",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/mark-read": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Mark a message read",
                "operationId": "message_mark_read_api_v1_mailbox_messages__message_id__mark_read_post",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/mark-unread": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Mark a message unread",
                "operationId": "message_mark_unread_api_v1_mailbox_messages__message_id__mark_unread_post",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/star": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Star a message",
                "operationId": "message_star_api_v1_mailbox_messages__message_id__star_post",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/unstar": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Unstar a message",
                "operationId": "message_unstar_api_v1_mailbox_messages__message_id__unstar_post",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/move": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Move a message to another folder",
                "operationId": "message_move_api_v1_mailbox_messages__message_id__move_post",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/MoveRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/trash": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Move a message to Trash",
                "description": "What the webmail's delete button calls. Recoverable by design.",
                "operationId": "message_trash_api_v1_mailbox_messages__message_id__trash_post",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/thread": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "The conversation a message belongs to",
                "description": "Oldest first. Threading follows RFC 5322 Message-ID / In-Reply-To / References, never subject lines -- subject matching collapses unrelated 'Re: hello' messages into one conversation.",
                "operationId": "message_thread_api_v1_mailbox_messages__message_id__thread_get",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/contacts": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Addresses this mailbox has written to",
                "description": "Harvested from the Sent folder, most-used first, for compose autocomplete. People WRITTEN TO only -- senders of received mail are deliberately excluded, or every cold email and newsletter in the inbox would become a suggestion. Colleagues nobody has written to yet come from the company directory instead.",
                "operationId": "contacts_api_v1_mailbox_contacts_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/send": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Send a message",
                "description": "Submits through Postfix and files a copy in Sent. The From address is always the signed-in mailbox: submission is trusted-network rather than SASL-authenticated, so Postfix's own sender-login check is bypassed and this endpoint is the only thing preventing one mailbox sending as another. Replies (`in_reply_to` set) flag the original \\Answered; forwards carry attachments over with `forward_attachments_from` + `attachment_indexes`. With `send_at` (ISO-8601) the message is stored in the Scheduled folder and sent at that time instead -- the response then carries `send_at` and the id it can be cancelled by.",
                "operationId": "send_message_api_v1_mailbox_messages_send_post",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/settings": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "The mailbox holder's own settings",
                "description": "Signature, display density, undo-send and real storage figures.",
                "operationId": "settings_show_api_v1_mailbox_settings_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Update the mailbox holder's settings",
                "description": "Partial update -- only the fields present are changed. The signature is sanitised against an allowlist before storage, because it is HTML this server later attaches to outgoing mail.",
                "operationId": "settings_update_api_v1_mailbox_settings_put",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateSettingsRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/security": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "The mailbox holder's security state",
                "description": "Two-factor status and what it protects. `protects` is part of the contract: mailbox 2FA gates the webmail sign-in only, never IMAP or SMTP, and the UI must not overclaim its reach.",
                "operationId": "security_show_api_v1_mailbox_security_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/security/2fa/begin": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Start two-factor enrolment",
                "description": "Generates a secret and recovery codes. Enrolment is NOT active until /confirm succeeds with a working code -- otherwise a mis-scanned QR would lock the holder out of their own mailbox.",
                "operationId": "two_factor_begin_api_v1_mailbox_security_2fa_begin_post",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/security/2fa/confirm": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Confirm two-factor enrolment with a code",
                "operationId": "two_factor_confirm_api_v1_mailbox_security_2fa_confirm_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/TwoFactorCodeRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/security/2fa/disable": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Turn two-factor off",
                "description": "Requires a current code, so a borrowed session cannot remove it.",
                "operationId": "two_factor_disable_api_v1_mailbox_security_2fa_disable_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/TwoFactorCodeRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/security/sessions": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Where this mailbox is signed in",
                "operationId": "security_sessions_api_v1_mailbox_security_sessions_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/security/sessions/{session_id}": {
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Sign out another device",
                "description": "Revokes one session. Refuses the caller's own -- signing yourself out from a list of other devices is almost always a misclick, and /logout is the deliberate way to do it.",
                "operationId": "security_revoke_session_api_v1_mailbox_security_sessions__session_id__delete",
                "parameters": [
                    {
                        "name": "session_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Session Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/ai/compose": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Draft or rewrite a message with AI",
                "description": "503 error_code ai_not_configured when no endpoint is set; 403 org_policy_blocked / not_entitled / consent_required / terms_version_stale when a Maya gate fails; 429 ai_quota_exhausted when the monthly allowance is spent. Responses carry ai_calls_remaining.",
                "operationId": "ai_compose_api_v1_mailbox_ai_compose_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/AiComposeRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/ai/summarize/{message_id}": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Summarise a message",
                "description": "Gated and metered exactly like /ai/compose. The whole-conversation variant is POST /ai/summarize/thread/{message_id} (routes/mailbox_ai.py).",
                "operationId": "ai_summarize_api_v1_mailbox_ai_summarize__message_id__post",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/forwarding": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Mail forwarding settings",
                "operationId": "forwarding_show_api_v1_mailbox_forwarding_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Update mail forwarding",
                "description": "Backed by Sieve `redirect :copy`, not a Postfix alias -- the alias route delivers two copies of every forwarded message.",
                "operationId": "forwarding_update_api_v1_mailbox_forwarding_put",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ForwardingRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/rules": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "The mailbox's filter rules",
                "operationId": "rules_show_api_v1_mailbox_rules_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Replace the mailbox's filter rules",
                "operationId": "rules_update_api_v1_mailbox_rules_put",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/RulesRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/vacation": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "The vacation responder",
                "operationId": "vacation_show_api_v1_mailbox_vacation_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Update the vacation responder",
                "description": "Replies at most once per sender per day, and only to mail actually addressed to this mailbox -- a message merely Cc'd to a list does not trigger one.",
                "operationId": "vacation_update_api_v1_mailbox_vacation_put",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/routes__mailbox__VacationRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/security/password": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Change this mailbox's password",
                "description": "Verifies `current_password` by IMAP LOGIN against Dovecot (the same check sign-in uses), enforces the platform password policy on `new_password`, stores the new bcrypt hash, flushes Dovecot's auth cache so IMAP/SMTP honour the change immediately, and signs out every OTHER session of this mailbox. The calling session stays signed in. Clears a pending forced change (`must_change_password`), so this is the one route a session carrying a temporary password may call besides sign-out. Failed `current_password` attempts count against the same lockout as sign-in.",
                "operationId": "change_password_api_v1_mailbox_security_password_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/routes__mailbox_password__PasswordChangeRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "401": {
                        "description": "`error_code: wrong_password` -- Dovecot refused current_password"
                    },
                    "409": {
                        "description": "`error_code: password_reused` -- new password equals the current"
                    },
                    "422": {
                        "description": "`error_code: weak_password` -- `msg` carries the failed rule"
                    },
                    "429": {
                        "description": "Too many failed attempts (shared with sign-in lockout)"
                    },
                    "502": {
                        "description": "Dovecot unreachable -- the password was not checked"
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/blocked-senders": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Senders this mailbox has blocked",
                "description": "Mail from a blocked address is filed to the Junk folder at delivery, before any rule, forward or vacation reply runs. Nothing is discarded.",
                "operationId": "blocked_senders_show_api_v1_mailbox_blocked_senders_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Block a sender",
                "description": "Adds one address. Matching is on the visible From address, whole address, case-insensitive. Blocking an address that is already blocked is not an error.",
                "operationId": "blocked_senders_add_api_v1_mailbox_blocked_senders_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/BlockSenderRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/blocked-senders/{address}": {
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Unblock a sender",
                "description": "Removes one address. Unblocking an address that is not blocked is not an error. Mail already filed to Junk stays where it is.",
                "operationId": "blocked_senders_remove_api_v1_mailbox_blocked_senders__address__delete",
                "parameters": [
                    {
                        "name": "address",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Address"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/insights": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "The mailbox's own analytics",
                "description": "Server-side aggregation over this mailbox's INBOX, Sent and Drafts headers: attention backlog, response times, weekly rhythm, relationships and hygiene, threaded by RFC 5322 identifiers. Every top-level block is independent -- a block that cannot be computed is omitted, and the client hides that section. Results are cached per window; window.to is the compute time. `refresh=true` recomputes, rate-limited per mailbox; when throttled, the cached copy is served.",
                "operationId": "insights_api_v1_mailbox_insights_get",
                "parameters": [
                    {
                        "name": "window",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "pattern": "^(30|90|180|365)d$",
                            "default": "90d",
                            "title": "Window"
                        }
                    },
                    {
                        "name": "refresh",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean",
                            "default": false,
                            "title": "Refresh"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/messages/{message_id}/context": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Who this message is with, and the shape of its conversation",
                "description": "Header-only context for one message: the history with its correspondent and the thread it belongs to. Always available -- no AI is involved and none is required. A message with no identifiable correspondent (a bounce, a self-note) omits the correspondent block.",
                "operationId": "message_context_api_v1_mailbox_messages__message_id__context_get",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/ai/terms": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "The current AI assistant terms",
                "description": "The full text of the terms the holder would be accepting, with its version and SHA-256. The client shows this text before POST /ai/consent; consent to one version is never consent to the next.",
                "operationId": "ai_terms_api_v1_mailbox_ai_terms_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/ai/consent": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "The mailbox holder's AI consent state",
                "description": "Current opt-in flags, the version accepted, when, the version currently in force, and the URL of the consent document. Deliberately available regardless of entitlement or org policy -- reading one's own consent state is never gated.",
                "operationId": "ai_consent_show_api_v1_mailbox_ai_consent_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Accept the AI assistant terms",
                "description": "Records the holder's acceptance of the CURRENT terms version -- 409 with error_code terms_version_stale if the submitted version is not current, so a client holding yesterday's text can never bind the holder to words they did not see. On success the acceptance is written to an append-only ledger together with a sealed PDF record (mailbox, both decisions, the full terms text as agreed, timestamp, actor), and the response carries its consent_id and document_url.",
                "operationId": "ai_consent_accept_api_v1_mailbox_ai_consent_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ConsentRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Withdraw AI consent entirely",
                "description": "Withdraws both the assistant and training decisions and writes a 'revoked' ledger entry with its own receipt document. Idempotent: with nothing to withdraw it succeeds without writing anything.",
                "operationId": "ai_consent_withdraw_api_v1_mailbox_ai_consent_delete",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/ai/consent/training": {
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Withdraw the training decision only",
                "description": "Turns off use of this mailbox's requests for model improvement while leaving the assistant itself consented. Idempotent.",
                "operationId": "ai_consent_withdraw_training_api_v1_mailbox_ai_consent_training_delete",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/ai/consent/history": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "The mailbox holder's consent history",
                "description": "Every acceptance and withdrawal, newest first, including any revoked_by_organisation entries written when an org admin set the AI policy to blocked. Each entry links its stored document.",
                "operationId": "ai_consent_history_api_v1_mailbox_ai_consent_history_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/ai/consent/{consent_id}/document": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Download one consent document",
                "description": "The stored PDF for one ledger entry -- own records only; another mailbox's id is a 404, not a 403.",
                "operationId": "ai_consent_document_api_v1_mailbox_ai_consent__consent_id__document_get",
                "parameters": [
                    {
                        "name": "consent_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Consent Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/ai/summarize/thread/{message_id}": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Summarise a whole conversation",
                "description": "Follows the message's RFC 5322 thread (shared/imap_mail.thread_for, read-only), stitches the most recent messages into one prompt, and summarises the conversation. Gated like every Maya endpoint; the response carries ai_calls_remaining.",
                "operationId": "ai_summarize_thread_api_v1_mailbox_ai_summarize_thread__message_id__post",
                "parameters": [
                    {
                        "name": "message_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Message Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/ai/classify": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Label a batch of messages",
                "description": "Classifies up to 20 messages by subject and preview into a closed label vocabulary with a confidence per item. One batch costs one call against the monthly allowance; the response carries ai_calls_remaining.",
                "operationId": "ai_classify_api_v1_mailbox_ai_classify_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ClassifyRequest"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/calendars": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Calendars in this mailbox",
                "operationId": "list_calendars_api_v1_mailbox_calendars_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/calendars/{calendar}/events": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Events overlapping a time range",
                "operationId": "list_events_api_v1_mailbox_calendars__calendar__events_get",
                "parameters": [
                    {
                        "name": "calendar",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Calendar"
                        }
                    },
                    {
                        "name": "start",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date-time",
                            "description": "ISO 8601, inclusive",
                            "title": "Start"
                        },
                        "description": "ISO 8601, inclusive"
                    },
                    {
                        "name": "end",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "format": "date-time",
                            "description": "ISO 8601, exclusive",
                            "title": "End"
                        },
                        "description": "ISO 8601, exclusive"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Create an event",
                "operationId": "create_event_api_v1_mailbox_calendars__calendar__events_post",
                "parameters": [
                    {
                        "name": "calendar",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Calendar"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/EventInput"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/calendars/{calendar}/events/{event_id}": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "One event",
                "operationId": "get_event_api_v1_mailbox_calendars__calendar__events__event_id__get",
                "parameters": [
                    {
                        "name": "calendar",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Calendar"
                        }
                    },
                    {
                        "name": "event_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Event Id"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Replace an event",
                "operationId": "update_event_api_v1_mailbox_calendars__calendar__events__event_id__put",
                "parameters": [
                    {
                        "name": "calendar",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Calendar"
                        }
                    },
                    {
                        "name": "event_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Event Id"
                        }
                    },
                    {
                        "name": "etag",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "string"
                                },
                                {
                                    "type": "null"
                                }
                            ],
                            "title": "Etag"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/EventInput"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Delete an event",
                "operationId": "delete_event_api_v1_mailbox_calendars__calendar__events__event_id__delete",
                "parameters": [
                    {
                        "name": "calendar",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Calendar"
                        }
                    },
                    {
                        "name": "event_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Event Id"
                        }
                    },
                    {
                        "name": "etag",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "string"
                                },
                                {
                                    "type": "null"
                                }
                            ],
                            "title": "Etag"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/calendar-subscriptions": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Subscription links for this mailbox",
                "operationId": "list_subscriptions_api_v1_mailbox_calendar_subscriptions_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Create a subscription link",
                "operationId": "create_subscription_api_v1_mailbox_calendar_subscriptions_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/SubscriptionInput"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "201": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/calendar-subscriptions/{token}": {
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Revoke a subscription link",
                "operationId": "revoke_subscription_api_v1_mailbox_calendar_subscriptions__token__delete",
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Token"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/calendar/rooms": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Rooms and equipment you can invite",
                "description": "The bookable rooms in this mailbox's own organisation.\n\nThis exists so that somebody making a meeting can PICK a room rather than\nknow its address by heart. Without it the address is the only handle a\nperson has, and an address typed from memory is a booking that silently\ngoes nowhere -- which is most of the reason rooms went unused.\n\nRead-only and mailbox-scoped on purpose. Creating a room is an admin\ndecision and stays on /calendar-resources behind an API key; seeing what\nyou may invite is not. The exposure is the same shape as free/busy --\nyour own organisation's directory, nobody else's -- so it is bounded the\nsame way, by organization_id and nothing the caller can supply.\n\nInactive rooms are omitted rather than shown greyed out: a room switched\noff is one nobody should be trying to book, and offering it only produces\nan invitation that is never answered.",
                "operationId": "list_rooms_api_v1_mailbox_calendar_rooms_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/calendar/free-busy": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "When are these people busy",
                "description": "Busy periods for each address, within the caller's own organization.\n\nTwo limits worth knowing, both reported rather than hidden:\n\n* A colleague at another company always comes back `known: false`. Neither\n  Google nor Microsoft exposes free/busy to strangers, so there is no\n  answer to give -- and showing an unknown person as free would invent one.\n* The attendee list is capped. This is an organization directory oracle:\n  unbounded, it is a way to enumerate who exists and when they work.",
                "operationId": "free_busy_api_v1_mailbox_calendar_free_busy_post",
                "requestBody": {
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/FreeBusyInput"
                            }
                        }
                    },
                    "required": true
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/calendar/invitations": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Invitations awaiting an answer",
                "description": "What is in this mailbox's scheduling inbox.\n\nThe same collection Apple Calendar and DAVx5 read, so answering here and\nanswering on a phone cannot disagree about what is still outstanding.",
                "operationId": "list_invitations_api_v1_mailbox_calendar_invitations_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/calendar/invitations/{invitation_id}/rsvp": {
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Answer an invitation",
                "description": "Accept, decline or tentatively accept.\n\nThe RFC 6638 dance, in order, and the order is what makes it work:\n\n  1. Read the message out of the scheduling inbox.\n  2. Set this mailbox's PARTSTAT on it, changing nothing else.\n  3. PUT it into the user's own calendar. **This is what sends the REPLY**\n     -- the scheduling plugin sees an attendee copy whose PARTSTAT\n     changed and generates the iTIP REPLY to the organizer. Nothing here\n     constructs that message by hand.\n  4. Remove the message from the scheduling inbox, which is the client's\n     job under RFC 6638. Skipping it leaves the invitation showing as\n     unanswered in every native client forever.\n\nStep 4 is deliberately best-effort: if it fails, the answer has already\nbeen sent and recorded, and failing the whole call would invite the user\nto answer twice.",
                "operationId": "rsvp_api_v1_mailbox_calendar_invitations__invitation_id__rsvp_post",
                "parameters": [
                    {
                        "name": "invitation_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Invitation Id"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/RsvpInput"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/address-book/books": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Address books this mailbox can see",
                "description": "The personal collection, plus anything shared with the mailbox.\n\n`read_only` is reported off the server's own privilege set rather than\nguessed from the name, so a UI can hide editing controls on a collection\nthe server would refuse to write anyway -- the company directory being the\ncase that matters.",
                "operationId": "list_books_api_v1_mailbox_address_book_books_get",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/address-book/contacts": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Saved contacts",
                "operationId": "list_contacts_api_v1_mailbox_address_book_contacts_get",
                "parameters": [
                    {
                        "name": "book",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "default",
                            "title": "Book"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "post": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Save a contact",
                "operationId": "create_contact_api_v1_mailbox_address_book_contacts_post",
                "parameters": [
                    {
                        "name": "book",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "default",
                            "title": "Book"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ContactInput"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        },
        "/api/v1/mailbox/address-book/contacts/{card_id}": {
            "get": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "One contact",
                "operationId": "get_contact_api_v1_mailbox_address_book_contacts__card_id__get",
                "parameters": [
                    {
                        "name": "card_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Card Id"
                        }
                    },
                    {
                        "name": "book",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "default",
                            "title": "Book"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "put": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Replace a contact",
                "description": "`etag` is the copy the caller last read.\n\nWithout it, two devices editing the same contact end with one silently\noverwriting the other. With it the second write is refused and the client\ncan re-read -- the same contract the calendar's event update uses.",
                "operationId": "update_contact_api_v1_mailbox_address_book_contacts__card_id__put",
                "parameters": [
                    {
                        "name": "card_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Card Id"
                        }
                    },
                    {
                        "name": "etag",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "string"
                                },
                                {
                                    "type": "null"
                                }
                            ],
                            "title": "Etag"
                        }
                    },
                    {
                        "name": "book",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "default",
                            "title": "Book"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ContactInput"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            },
            "delete": {
                "tags": [
                    "Mailbox API"
                ],
                "summary": "Delete a contact",
                "operationId": "delete_contact_api_v1_mailbox_address_book_contacts__card_id__delete",
                "parameters": [
                    {
                        "name": "card_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Card Id"
                        }
                    },
                    {
                        "name": "etag",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "anyOf": [
                                {
                                    "type": "string"
                                },
                                {
                                    "type": "null"
                                }
                            ],
                            "title": "Etag"
                        }
                    },
                    {
                        "name": "book",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "default",
                            "title": "Book"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": []
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "MailboxToken": []
                    }
                ]
            }
        }
    }
}
