{
  "components": {
    "schemas": {
      "AcceptInvitationRequest": {
        "description": "Accept an invitation as a brand-new user: set the password for the account\nbeing created. (Existing users accept via the authenticated endpoint and send\nno body.)",
        "properties": {
          "password": {
            "title": "Password",
            "type": "string"
          }
        },
        "required": [
          "password"
        ],
        "title": "AcceptInvitationRequest",
        "type": "object"
      },
      "AcceptedEvent": {
        "description": "One recorded event: which recipient it's for and its id (for status).",
        "properties": {
          "event_id": {
            "title": "Event Id",
            "type": "string"
          },
          "external_id": {
            "title": "External Id",
            "type": "string"
          }
        },
        "required": [
          "external_id",
          "event_id"
        ],
        "title": "AcceptedEvent",
        "type": "object"
      },
      "AccessTokenResponse": {
        "properties": {
          "access_token": {
            "title": "Access Token",
            "type": "string"
          },
          "token_type": {
            "default": "bearer",
            "title": "Token Type",
            "type": "string"
          }
        },
        "required": [
          "access_token"
        ],
        "title": "AccessTokenResponse",
        "type": "object"
      },
      "AffectedTemplateResponse": {
        "description": "A template that uses variables its notification type no longer exposes.",
        "properties": {
          "id": {
            "title": "Id",
            "type": "string"
          },
          "notification_type_key": {
            "title": "Notification Type Key",
            "type": "string"
          },
          "unknown_variables": {
            "items": {
              "type": "string"
            },
            "title": "Unknown Variables",
            "type": "array"
          }
        },
        "required": [
          "id",
          "notification_type_key",
          "unknown_variables"
        ],
        "title": "AffectedTemplateResponse",
        "type": "object"
      },
      "ApiKeyResponse": {
        "description": "Listing shape \u2014 never includes the secret or its digest.",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "prefix": {
            "title": "Prefix",
            "type": "string"
          },
          "revoked_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revoked At"
          }
        },
        "required": [
          "id",
          "name",
          "prefix",
          "created_at",
          "revoked_at"
        ],
        "title": "ApiKeyResponse",
        "type": "object"
      },
      "AttributeValueRequest": {
        "additionalProperties": false,
        "properties": {
          "value": {
            "examples": [
              "Ada"
            ],
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "value"
        ],
        "title": "AttributeValueRequest",
        "type": "object"
      },
      "BillingOverviewResponse": {
        "properties": {
          "billing_period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Billing Period"
          },
          "checkout": {
            "$ref": "#/components/schemas/CheckoutConfigResponse"
          },
          "current_period_end": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Period End"
          },
          "has_billing_account": {
            "title": "Has Billing Account",
            "type": "boolean"
          },
          "limits": {
            "$ref": "#/components/schemas/PlanLimitsResponse"
          },
          "plan": {
            "title": "Plan",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "plan",
          "status",
          "billing_period",
          "current_period_end",
          "limits",
          "has_billing_account",
          "checkout"
        ],
        "title": "BillingOverviewResponse",
        "type": "object"
      },
      "BillingPeriod": {
        "description": "How often a paid tier renews. Mirrors the pricing page's monthly/annual\ntoggle; each (plan, period) pair maps to one Paddle price id.",
        "enum": [
          "monthly",
          "annual"
        ],
        "title": "BillingPeriod",
        "type": "string"
      },
      "BrandingResponse": {
        "properties": {
          "from_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Address"
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Name"
          },
          "is_default": {
            "description": "The tenant's fallback brand, used when a trigger names no brand or an unknown one. Exactly one per tenant, provisioned at signup, and it cannot be deleted.",
            "title": "Is Default",
            "type": "boolean"
          },
          "key": {
            "title": "Key",
            "type": "string"
          },
          "values": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Values",
            "type": "object"
          }
        },
        "required": [
          "key",
          "values",
          "is_default",
          "from_address",
          "from_name"
        ],
        "title": "BrandingResponse",
        "type": "object"
      },
      "ChangeMemberRoleRequest": {
        "description": "Change an existing member's role. `role` must be admin/member/viewer \u2014\nowner is rejected (422); ownership isn't assigned via a role change.",
        "properties": {
          "role": {
            "title": "Role",
            "type": "string"
          }
        },
        "required": [
          "role"
        ],
        "title": "ChangeMemberRoleRequest",
        "type": "object"
      },
      "ChangePlanRequest": {
        "additionalProperties": false,
        "description": "Move an existing paid subscription to this tier/period. The fields *are*\nthe domain enums, so an unknown value is a clean 422 listing the permitted\nones \u2014 the same way the other modules type their enum fields.",
        "properties": {
          "period": {
            "$ref": "#/components/schemas/BillingPeriod"
          },
          "plan": {
            "$ref": "#/components/schemas/Plan"
          }
        },
        "required": [
          "plan",
          "period"
        ],
        "title": "ChangePlanRequest",
        "type": "object"
      },
      "Channel": {
        "description": "A delivery channel a notification can be sent over.\n\nThis is an enum (not a bare string) so adding SMS / WHATSAPP later is a\none-line change and every per-channel mapping (notification-type defaults,\ncontact preferences) extends automatically. Crucially, a newly-added channel\nis **opted out by default** everywhere: `NotificationType.default_for` returns\nFalse for a channel absent from `channel_defaults`, and a contact has no\npreference until they set one \u2014 so an existing install gains a channel that\ndelivers to nobody until a tenant explicitly enables it. That's why adding a\nmember needs no data migration.\n\nSubclassing `str` makes members compare/serialize as their value\n(\"email\"), which keeps JSON and dict keys clean.",
        "enum": [
          "email",
          "inbox",
          "push",
          "web_push"
        ],
        "title": "Channel",
        "type": "string"
      },
      "ChannelPreferenceResponse": {
        "properties": {
          "channel": {
            "$ref": "#/components/schemas/Channel"
          },
          "enabled": {
            "title": "Enabled",
            "type": "boolean"
          },
          "overridden": {
            "title": "Overridden",
            "type": "boolean"
          }
        },
        "required": [
          "channel",
          "enabled",
          "overridden"
        ],
        "title": "ChannelPreferenceResponse",
        "type": "object"
      },
      "CheckoutConfigResponse": {
        "description": "Everything the console needs to open the Paddle.js overlay checkout:\nthe client-side token (public by design \u2014 it can only open checkouts), the\nenvironment flag, the tenant reference to stamp into `customData`, and the\nprice id per self-serve tier (`\"pro:monthly\"` \u2192 `pri_\u2026`).\n\n`tenant_ref` is *signed* rather than a raw tenant id: `customData` is set in\nthe browser, so an unsigned id would be a claim anyone could make about any\ntenant. Minted here because this endpoint is already authenticated and\ntenant-scoped \u2014 a caller can only ever get a reference to their own tenant.",
        "properties": {
          "client_token": {
            "title": "Client Token",
            "type": "string"
          },
          "environment": {
            "title": "Environment",
            "type": "string"
          },
          "prices": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Prices",
            "type": "object"
          },
          "tenant_ref": {
            "title": "Tenant Ref",
            "type": "string"
          }
        },
        "required": [
          "client_token",
          "environment",
          "tenant_ref",
          "prices"
        ],
        "title": "CheckoutConfigResponse",
        "type": "object"
      },
      "ContactImportRowRequest": {
        "additionalProperties": false,
        "description": "One row of an import.\n\nEvery value stays a **raw string** here on purpose. Validating addresses in\nthe DTO would make one malformed row a 422 for the whole file, which is\nexactly the behaviour bulk import exists to avoid; the row is converted to\nvalue objects one at a time instead, and a failure is reported against that\nrow while the rest import.\n\nA field that is absent is left untouched on an existing contact; a field\npresent but empty clears it. `external_id` is required because it is the key\nthe upsert matches on.",
        "properties": {
          "attributes": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              {
                "first_name": "Ada",
                "tier": "gold"
              }
            ],
            "title": "Attributes"
          },
          "emails": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              [
                "a@example.com"
              ]
            ],
            "title": "Emails"
          },
          "external_id": {
            "examples": [
              "crm-12345"
            ],
            "title": "External Id",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "phones": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              [
                "+15551234567"
              ]
            ],
            "title": "Phones"
          }
        },
        "required": [
          "external_id"
        ],
        "title": "ContactImportRowRequest",
        "type": "object"
      },
      "ContactLanguageRequest": {
        "additionalProperties": false,
        "description": "Set (or clear) a contact's preferred language. `null` clears it, reverting\nto the default template.",
        "properties": {
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          }
        },
        "title": "ContactLanguageRequest",
        "type": "object"
      },
      "ContactPage": {
        "description": "A page of contacts plus the total matching the filter, for pagination.",
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/ContactResponse"
            },
            "title": "Items",
            "type": "array"
          },
          "limit": {
            "title": "Limit",
            "type": "integer"
          },
          "offset": {
            "title": "Offset",
            "type": "integer"
          },
          "total": {
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total",
          "limit",
          "offset"
        ],
        "title": "ContactPage",
        "type": "object"
      },
      "ContactPreferencesResponse": {
        "description": "The whole contact preference centre in one payload: the saved preferred\n`language` (null = default) plus the notification `types` matrix. A single\ncontact-token read renders everything the contact previously chose.",
        "properties": {
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language"
          },
          "types": {
            "items": {
              "$ref": "#/components/schemas/TypePreferenceResponse"
            },
            "title": "Types",
            "type": "array"
          }
        },
        "required": [
          "language",
          "types"
        ],
        "title": "ContactPreferencesResponse",
        "type": "object"
      },
      "ContactResponse": {
        "properties": {
          "attributes": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Attributes",
            "type": "object"
          },
          "emails": {
            "items": {
              "type": "string"
            },
            "title": "Emails",
            "type": "array"
          },
          "external_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Id"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "The contact's preferred language tag (e.g. \"es\"), or null for the language-less default. Set at create or via PUT /v1/contacts/{id}/language \u2014 deliberately NOT part of the whole-resource PUT, so a partial-shaped update can't silently clear it.",
            "title": "Language"
          },
          "phones": {
            "items": {
              "type": "string"
            },
            "title": "Phones",
            "type": "array"
          },
          "preferences": {
            "items": {
              "$ref": "#/components/schemas/PreferenceDTO"
            },
            "title": "Preferences",
            "type": "array"
          },
          "push_subscriptions": {
            "items": {
              "$ref": "#/components/schemas/PushSubscriptionDTO"
            },
            "title": "Push Subscriptions",
            "type": "array"
          }
        },
        "required": [
          "id",
          "external_id",
          "language",
          "emails",
          "phones",
          "push_subscriptions",
          "attributes",
          "preferences"
        ],
        "title": "ContactResponse",
        "type": "object"
      },
      "ContactTokenRequest": {
        "additionalProperties": false,
        "description": "A tenant backend asking for a short-lived token scoped to one of its\ncontacts (by the tenant's own `external_id`), to hand to that contact's\nbrowser.",
        "properties": {
          "external_id": {
            "examples": [
              "crm-12345"
            ],
            "title": "External Id",
            "type": "string"
          }
        },
        "required": [
          "external_id"
        ],
        "title": "ContactTokenRequest",
        "type": "object"
      },
      "ContactTokenResponse": {
        "description": "A contact-scoped bearer token. The frontend uses it to call the\ncontact-facing endpoints (inbox, push tokens, preferences, the SSE stream) for\n*this* contact only; re-mint from the tenant's session when it expires.\n\n`contact_id` is the contact's *internal* id \u2014 the one the contact-facing URLs\ntake (e.g. `/v1/contacts/{contact_id}/stream`). The backend passes the tenant's\nown `external_id` in and gets both the token and the internal id back, so it\ncan hand the browser everything it needs without tracking internal ids itself.",
        "properties": {
          "contact_id": {
            "title": "Contact Id",
            "type": "string"
          },
          "expires_in": {
            "title": "Expires In",
            "type": "integer"
          },
          "token": {
            "title": "Token",
            "type": "string"
          },
          "token_type": {
            "default": "bearer",
            "title": "Token Type",
            "type": "string"
          }
        },
        "required": [
          "token",
          "expires_in",
          "contact_id"
        ],
        "title": "ContactTokenResponse",
        "type": "object"
      },
      "CreateBrandingRequest": {
        "additionalProperties": false,
        "properties": {
          "from_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "hello@acme.com"
            ],
            "title": "From Address"
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "Acme"
            ],
            "title": "From Name"
          },
          "key": {
            "examples": [
              "acme"
            ],
            "title": "Key",
            "type": "string"
          },
          "values": {
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "color": "#0a0",
                "logo": "https://cdn.acme.test/logo.png"
              }
            ],
            "title": "Values",
            "type": "object"
          }
        },
        "required": [
          "key"
        ],
        "title": "CreateBrandingRequest",
        "type": "object"
      },
      "CreateContactRequest": {
        "additionalProperties": false,
        "description": "Initial state of a new contact: an optional `external_id` plus the same\nmutable collections as a full update (all optional, defaulting to empty), so a\ncontact can be created fully populated in one call or bare and filled in via\nthe sub-resource endpoints. `language` is settable at create; afterwards it's\nchanged only via its own endpoint (it's deliberately *not* in the whole-resource\nupdate, so a partial-shaped PUT can't silently clear it).",
        "properties": {
          "attributes": {
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "first_name": "Ada"
              }
            ],
            "title": "Attributes",
            "type": "object"
          },
          "emails": {
            "examples": [
              [
                "a@example.com"
              ]
            ],
            "items": {
              "type": "string"
            },
            "title": "Emails",
            "type": "array"
          },
          "external_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "crm-12345"
            ],
            "title": "External Id"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "phones": {
            "examples": [
              [
                "+15551234567"
              ]
            ],
            "items": {
              "type": "string"
            },
            "title": "Phones",
            "type": "array"
          },
          "preferences": {
            "items": {
              "$ref": "#/components/schemas/PreferenceDTO"
            },
            "title": "Preferences",
            "type": "array"
          },
          "push_subscriptions": {
            "items": {
              "$ref": "#/components/schemas/PushSubscriptionDTO"
            },
            "title": "Push Subscriptions",
            "type": "array"
          }
        },
        "title": "CreateContactRequest",
        "type": "object"
      },
      "CreateEmailTemplateRequest": {
        "additionalProperties": false,
        "properties": {
          "body": {
            "examples": [
              "Hi {{ contact.first_name }}, your order is on its way."
            ],
            "title": "Body",
            "type": "string"
          },
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "acme"
            ],
            "title": "Branding Key"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "notification_type_key": {
            "examples": [
              "order_shipped"
            ],
            "title": "Notification Type Key",
            "type": "string"
          },
          "subject": {
            "examples": [
              "Your order has shipped"
            ],
            "title": "Subject",
            "type": "string"
          }
        },
        "required": [
          "notification_type_key",
          "subject",
          "body"
        ],
        "title": "CreateEmailTemplateRequest",
        "type": "object"
      },
      "CreateInboxTemplateRequest": {
        "additionalProperties": false,
        "properties": {
          "body": {
            "examples": [
              "Hi {{ contact.first_name }}, your order is on its way."
            ],
            "title": "Body",
            "type": "string"
          },
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "acme"
            ],
            "title": "Branding Key"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "notification_type_key": {
            "examples": [
              "order_shipped"
            ],
            "title": "Notification Type Key",
            "type": "string"
          },
          "title": {
            "examples": [
              "Your order shipped"
            ],
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "notification_type_key",
          "title",
          "body"
        ],
        "title": "CreateInboxTemplateRequest",
        "type": "object"
      },
      "CreateNotificationTypeRequest": {
        "additionalProperties": false,
        "properties": {
          "allows_opt_out": {
            "default": true,
            "description": "Whether contacts may override this type's channel defaults. Set false for transactional notifications a recipient must not be able to switch off (email verification, password reset). This does NOT force delivery on every channel \u2014 channel_defaults still decides which channels fire; only the contact's veto is removed.",
            "examples": [
              true
            ],
            "title": "Allows Opt Out",
            "type": "boolean"
          },
          "channel_defaults": {
            "additionalProperties": {
              "type": "boolean"
            },
            "examples": [
              {
                "email": true
              }
            ],
            "propertyNames": {
              "$ref": "#/components/schemas/Channel"
            },
            "title": "Channel Defaults",
            "type": "object"
          },
          "key": {
            "examples": [
              "order_shipped"
            ],
            "title": "Key",
            "type": "string"
          },
          "variables": {
            "examples": [
              [
                "first_name",
                "order_id"
              ]
            ],
            "items": {
              "type": "string"
            },
            "title": "Variables",
            "type": "array",
            "uniqueItems": true
          }
        },
        "required": [
          "key"
        ],
        "title": "CreateNotificationTypeRequest",
        "type": "object"
      },
      "CreatePushTemplateRequest": {
        "additionalProperties": false,
        "properties": {
          "body": {
            "default": "",
            "examples": [
              "It's on its way."
            ],
            "title": "Body",
            "type": "string"
          },
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "acme"
            ],
            "title": "Branding Key"
          },
          "data": {
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "deep_link": "/orders/{{ order_id }}"
              }
            ],
            "title": "Data",
            "type": "object"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "notification_type_key": {
            "examples": [
              "order_shipped"
            ],
            "title": "Notification Type Key",
            "type": "string"
          },
          "title": {
            "default": "",
            "examples": [
              "Your order shipped"
            ],
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "notification_type_key"
        ],
        "title": "CreatePushTemplateRequest",
        "type": "object"
      },
      "CreateTenantRequest": {
        "description": "Create a new account (tenant) owned by the signed-in user. `name` is the\ndisplay label; blank/whitespace-only is a clean 422 (mirrors the Tenant rule).",
        "properties": {
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "CreateTenantRequest",
        "type": "object"
      },
      "CreateWebPushTemplateRequest": {
        "additionalProperties": false,
        "properties": {
          "badge": {
            "default": "",
            "examples": [
              "https://example.com/badge.png"
            ],
            "title": "Badge",
            "type": "string"
          },
          "body": {
            "default": "",
            "examples": [
              "It's on its way."
            ],
            "title": "Body",
            "type": "string"
          },
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "acme"
            ],
            "title": "Branding Key"
          },
          "data": {
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "order_id": "{{ order_id }}"
              }
            ],
            "title": "Data",
            "type": "object"
          },
          "icon": {
            "default": "",
            "examples": [
              "{{ brand.icon_url }}"
            ],
            "title": "Icon",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "notification_type_key": {
            "examples": [
              "order_shipped"
            ],
            "title": "Notification Type Key",
            "type": "string"
          },
          "title": {
            "examples": [
              "Your order shipped"
            ],
            "title": "Title",
            "type": "string"
          },
          "url": {
            "default": "",
            "examples": [
              "https://example.com/orders/{{ order_id }}"
            ],
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "title",
          "notification_type_key"
        ],
        "title": "CreateWebPushTemplateRequest",
        "type": "object"
      },
      "DataRequestBody": {
        "properties": {
          "kind": {
            "description": "What is being asked for. `export` requests a copy of everything in the account; `deletion` requests that the account and its data be erased. Both are actioned by a human, so neither takes effect immediately and submitting one changes nothing about the account.",
            "enum": [
              "export",
              "deletion"
            ],
            "title": "Kind",
            "type": "string"
          }
        },
        "required": [
          "kind"
        ],
        "title": "DataRequestBody",
        "type": "object"
      },
      "DataRequestResponse": {
        "description": "No id, because nothing is stored to have one. The console shows the\nacknowledgement and the address to chase, which is all a caller can act on.",
        "properties": {
          "contact_email": {
            "description": "Where to follow up, and where to write if this ever fails.",
            "title": "Contact Email",
            "type": "string"
          },
          "kind": {
            "enum": [
              "export",
              "deletion"
            ],
            "title": "Kind",
            "type": "string"
          }
        },
        "required": [
          "kind",
          "contact_email"
        ],
        "title": "DataRequestResponse",
        "type": "object"
      },
      "DeliveryChannel": {
        "description": "Which store to read. `EVENT` is the trigger intake itself \u2014 not a delivery\nchannel, but the same question (\"what did we send?\") one level up, and the\nparent of the other three.",
        "enum": [
          "event",
          "email",
          "push",
          "inbox",
          "web_push"
        ],
        "title": "DeliveryChannel",
        "type": "string"
      },
      "DeliveryDetail": {
        "description": "A single delivery with its frozen content. `body` is served only here, never\nin the list \u2014 it is unbounded text and 50 of them per page would be brutal.\n\n`body_retained` distinguishes \"we still hold the rendered message\" from \"we\nno longer do\". It was added ahead of need, so that offloading bodies (to S3\non the SaaS) or dropping them after a retention window (on-prem) would be an\nadditive change rather than a breaking one. **Contact erasure is the first\nthing that actually makes it false**: erasing a contact blanks the rendered\ncontent of everything already sent to them, and a `body` of `null` has to be\ndistinguishable from a message that was genuinely empty.",
        "properties": {
          "body": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Body"
          },
          "body_retained": {
            "default": true,
            "title": "Body Retained",
            "type": "boolean"
          },
          "data": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Data"
          },
          "item": {
            "$ref": "#/components/schemas/DeliveryItem"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "variables": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/JsonValue"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Variables"
          }
        },
        "required": [
          "item"
        ],
        "title": "DeliveryDetail",
        "type": "object"
      },
      "DeliveryItem": {
        "properties": {
          "attempts": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Attempts"
          },
          "channel": {
            "$ref": "#/components/schemas/DeliveryChannel"
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language"
          },
          "next_attempt_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Attempt At"
          },
          "notification_event_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notification Event Id"
          },
          "notification_type_key": {
            "title": "Notification Type Key",
            "type": "string"
          },
          "provider": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Provider"
          },
          "recipient": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Recipient"
          },
          "redacted": {
            "default": false,
            "title": "Redacted",
            "type": "boolean"
          },
          "sent_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sent At"
          },
          "status": {
            "title": "Status",
            "type": "string"
          },
          "summary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary"
          }
        },
        "required": [
          "id",
          "channel",
          "status",
          "created_at",
          "notification_type_key"
        ],
        "title": "DeliveryItem",
        "type": "object"
      },
      "DeliveryPage": {
        "properties": {
          "items": {
            "items": {
              "$ref": "#/components/schemas/DeliveryItem"
            },
            "title": "Items",
            "type": "array"
          },
          "limit": {
            "title": "Limit",
            "type": "integer"
          },
          "offset": {
            "title": "Offset",
            "type": "integer"
          },
          "total": {
            "title": "Total",
            "type": "integer"
          }
        },
        "required": [
          "items",
          "total",
          "limit",
          "offset"
        ],
        "title": "DeliveryPage",
        "type": "object"
      },
      "DeliveryStatsResponse": {
        "description": "Tenant delivery counts by status across the outboxes, for the console\ndashboard. Each map is status-string \u2192 count; statuses with no rows are\nomitted.",
        "properties": {
          "emails": {
            "additionalProperties": {
              "type": "integer"
            },
            "examples": [
              {
                "failed": 1,
                "sent": 9
              }
            ],
            "title": "Emails",
            "type": "object"
          },
          "emails_retrying": {
            "default": 0,
            "examples": [
              3
            ],
            "title": "Emails Retrying",
            "type": "integer"
          },
          "events": {
            "additionalProperties": {
              "type": "integer"
            },
            "examples": [
              {
                "pending": 1,
                "processed": 12
              }
            ],
            "title": "Events",
            "type": "object"
          },
          "pushes": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Mobile push only (Expo/FCM/APNs/OneSignal). Browser sends are counted under `web_pushes` \u2014 they share a store but are separate channels, and one number over both hides which of the two is failing.",
            "examples": [
              {
                "delivered": 5
              }
            ],
            "title": "Pushes",
            "type": "object"
          },
          "pushes_retrying": {
            "default": 0,
            "examples": [
              0
            ],
            "title": "Pushes Retrying",
            "type": "integer"
          },
          "web_pushes": {
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Browser push (Web Push/VAPID), the `web_push` channel.",
            "examples": [
              {
                "delivered": 2
              }
            ],
            "title": "Web Pushes",
            "type": "object"
          },
          "web_pushes_retrying": {
            "default": 0,
            "examples": [
              0
            ],
            "title": "Web Pushes Retrying",
            "type": "integer"
          }
        },
        "required": [
          "events",
          "emails",
          "pushes",
          "web_pushes"
        ],
        "title": "DeliveryStatsResponse",
        "type": "object"
      },
      "DnsRecord": {
        "properties": {
          "name": {
            "title": "Name",
            "type": "string"
          },
          "priority": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Priority"
          },
          "type": {
            "title": "Type",
            "type": "string"
          },
          "value": {
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "type",
          "name",
          "value"
        ],
        "title": "DnsRecord",
        "type": "object"
      },
      "EmailTemplateResponse": {
        "properties": {
          "body": {
            "title": "Body",
            "type": "string"
          },
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Branding Key"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language"
          },
          "notification_type_key": {
            "title": "Notification Type Key",
            "type": "string"
          },
          "subject": {
            "title": "Subject",
            "type": "string"
          },
          "variables": {
            "items": {
              "type": "string"
            },
            "title": "Variables",
            "type": "array"
          }
        },
        "required": [
          "id",
          "notification_type_key",
          "branding_key",
          "language",
          "variables",
          "subject",
          "body"
        ],
        "title": "EmailTemplateResponse",
        "type": "object"
      },
      "EmailTransportRequest": {
        "additionalProperties": false,
        "properties": {
          "from_address": {
            "examples": [
              "orders@acme.com"
            ],
            "title": "From Address",
            "type": "string"
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "Acme"
            ],
            "title": "From Name"
          },
          "mailgun": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MailgunTransportInput"
              },
              {
                "type": "null"
              }
            ]
          },
          "provider": {
            "enum": [
              "smtp",
              "ses",
              "sendgrid",
              "mailgun"
            ],
            "title": "Provider",
            "type": "string"
          },
          "sendgrid": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SendGridTransportInput"
              },
              {
                "type": "null"
              }
            ]
          },
          "ses": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SesTransportInput"
              },
              {
                "type": "null"
              }
            ]
          },
          "smtp": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SmtpTransportInput"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "provider",
          "from_address"
        ],
        "title": "EmailTransportRequest",
        "type": "object"
      },
      "EmailTransportResponse": {
        "description": "`provider: \"platform\"` (all sections null) is the no-config state \u2014 a\nreal answer, so GET always returns 200 rather than 404ing the default.",
        "properties": {
          "from_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Address"
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Name"
          },
          "mailgun": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MailgunTransportView"
              },
              {
                "type": "null"
              }
            ]
          },
          "provider": {
            "anyOf": [
              {
                "const": "platform",
                "type": "string"
              },
              {
                "$ref": "#/components/schemas/TransportProvider"
              }
            ],
            "title": "Provider"
          },
          "sendgrid": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SendGridTransportView"
              },
              {
                "type": "null"
              }
            ]
          },
          "ses": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SesTransportView"
              },
              {
                "type": "null"
              }
            ]
          },
          "smtp": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SmtpTransportView"
              },
              {
                "type": "null"
              }
            ]
          },
          "updated_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At"
          }
        },
        "required": [
          "provider",
          "from_address",
          "from_name",
          "updated_at"
        ],
        "title": "EmailTransportResponse",
        "type": "object"
      },
      "EmailValueRequest": {
        "additionalProperties": false,
        "properties": {
          "value": {
            "examples": [
              "a@example.com"
            ],
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "value"
        ],
        "title": "EmailValueRequest",
        "type": "object"
      },
      "ErasureRequest": {
        "description": "Which recipient to erase, named the tenant's own way.",
        "properties": {
          "external_id": {
            "description": "Your identifier for the person, the same value you pass to `POST /v1/notifications`. Used rather than our contact id because the data this reaches may exist when no contact does.",
            "minLength": 1,
            "title": "External Id",
            "type": "string"
          }
        },
        "required": [
          "external_id"
        ],
        "title": "ErasureRequest",
        "type": "object"
      },
      "ErasureResponse": {
        "description": "What an erasure touched \u2014 returned so the caller can evidence the request.",
        "properties": {
          "contact_deleted": {
            "description": "Whether a contact existed for this external id and was deleted.",
            "title": "Contact Deleted",
            "type": "boolean"
          },
          "external_id": {
            "title": "External Id",
            "type": "string"
          },
          "rows_cancelled": {
            "description": "Of those, how many were still queued and have been stopped, so they can never be delivered. Always less than or equal to rows_redacted.",
            "title": "Rows Cancelled",
            "type": "integer"
          },
          "rows_redacted": {
            "description": "Delivery records whose personal data was blanked, across all channels.",
            "title": "Rows Redacted",
            "type": "integer"
          }
        },
        "required": [
          "external_id",
          "contact_deleted",
          "rows_redacted",
          "rows_cancelled"
        ],
        "title": "ErasureResponse",
        "type": "object"
      },
      "ErrorResponse": {
        "description": "The body shape every error handler returns.",
        "properties": {
          "detail": {
            "title": "Detail",
            "type": "string"
          }
        },
        "required": [
          "detail"
        ],
        "title": "ErrorResponse",
        "type": "object"
      },
      "EventDeliveriesResponse": {
        "description": "Every channel's outcome for one trigger \u2014 the cross-channel drill-down.",
        "properties": {
          "emails": {
            "items": {
              "$ref": "#/components/schemas/DeliveryItem"
            },
            "title": "Emails",
            "type": "array"
          },
          "event": {
            "$ref": "#/components/schemas/DeliveryItem"
          },
          "inbox": {
            "items": {
              "$ref": "#/components/schemas/DeliveryItem"
            },
            "title": "Inbox",
            "type": "array"
          },
          "pushes": {
            "items": {
              "$ref": "#/components/schemas/DeliveryItem"
            },
            "title": "Pushes",
            "type": "array"
          }
        },
        "required": [
          "event",
          "inbox",
          "emails",
          "pushes"
        ],
        "title": "EventDeliveriesResponse",
        "type": "object"
      },
      "EventStatus": {
        "description": "Lifecycle of a recorded event. `PENDING` until the fan-out worker picks it\nup; `PROCESSED` once fan-out finished (possibly with per-channel errors noted\nin `last_error`); `FAILED` when the event couldn't be processed at all (the\nrecipient / type didn't resolve, so no channel could be attempted). An unknown\nbranding is *not* fatal \u2014 fan-out falls back to the tenant default.",
        "enum": [
          "pending",
          "processed",
          "failed"
        ],
        "title": "EventStatus",
        "type": "string"
      },
      "ExpoTransportInput": {
        "additionalProperties": false,
        "properties": {
          "access_token": {
            "examples": [
              "ExpoAccessToken-xxxx"
            ],
            "title": "Access Token",
            "type": "string"
          }
        },
        "required": [
          "access_token"
        ],
        "title": "ExpoTransportInput",
        "type": "object"
      },
      "ExpoTransportView": {
        "properties": {
          "has_access_token": {
            "title": "Has Access Token",
            "type": "boolean"
          }
        },
        "required": [
          "has_access_token"
        ],
        "title": "ExpoTransportView",
        "type": "object"
      },
      "FcmTransportInput": {
        "additionalProperties": false,
        "properties": {
          "service_account_json": {
            "examples": [
              "{\"type\":\"service_account\", ...}"
            ],
            "title": "Service Account Json",
            "type": "string"
          }
        },
        "required": [
          "service_account_json"
        ],
        "title": "FcmTransportInput",
        "type": "object"
      },
      "FcmTransportView": {
        "properties": {
          "client_email": {
            "title": "Client Email",
            "type": "string"
          },
          "has_private_key": {
            "title": "Has Private Key",
            "type": "boolean"
          },
          "project_id": {
            "title": "Project Id",
            "type": "string"
          }
        },
        "required": [
          "project_id",
          "client_email",
          "has_private_key"
        ],
        "title": "FcmTransportView",
        "type": "object"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "title": "Detail",
            "type": "array"
          }
        },
        "title": "HTTPValidationError",
        "type": "object"
      },
      "ImportContactsRequest": {
        "additionalProperties": false,
        "description": "A batch of rows to create or update, keyed by `external_id`.",
        "properties": {
          "contacts": {
            "description": "Up to 500 rows. Each is matched to an existing contact by `external_id` and updated, or created if there is none. A field you omit is left as it was; a field you send empty is cleared.",
            "items": {
              "$ref": "#/components/schemas/ContactImportRowRequest"
            },
            "maxItems": 500,
            "minItems": 1,
            "title": "Contacts",
            "type": "array"
          }
        },
        "required": [
          "contacts"
        ],
        "title": "ImportContactsRequest",
        "type": "object"
      },
      "ImportContactsResponse": {
        "additionalProperties": false,
        "description": "Per-row outcomes for the batch.\n\nA row-level problem (a malformed address, a blank id, the same\n`external_id` twice) is reported here while every other row still imports.\n\nA malformed request *shape* is not: a value of the wrong JSON type, or an\nunexpected key, is rejected before any row is read and returns 422 for the\nwhole batch. What is checked per row is the content of the strings.",
        "properties": {
          "created": {
            "title": "Created",
            "type": "integer"
          },
          "failed": {
            "title": "Failed",
            "type": "integer"
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/ImportRowResultResponse"
            },
            "title": "Rows",
            "type": "array"
          },
          "updated": {
            "title": "Updated",
            "type": "integer"
          }
        },
        "required": [
          "created",
          "updated",
          "failed",
          "rows"
        ],
        "title": "ImportContactsResponse",
        "type": "object"
      },
      "ImportRowResultResponse": {
        "additionalProperties": false,
        "description": "What happened to one row, and where it was.",
        "properties": {
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the row failed. Null unless outcome is failed.",
            "title": "Error"
          },
          "external_id": {
            "title": "External Id",
            "type": "string"
          },
          "index": {
            "description": "The row's position in the submitted `contacts` array, so a client can point at the line of the file the user uploaded.",
            "title": "Index",
            "type": "integer"
          },
          "outcome": {
            "enum": [
              "created",
              "updated",
              "failed"
            ],
            "title": "Outcome",
            "type": "string"
          }
        },
        "required": [
          "index",
          "external_id",
          "outcome"
        ],
        "title": "ImportRowResultResponse",
        "type": "object"
      },
      "InboxTemplateResponse": {
        "properties": {
          "body": {
            "title": "Body",
            "type": "string"
          },
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Branding Key"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language"
          },
          "notification_type_key": {
            "title": "Notification Type Key",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "variables": {
            "items": {
              "type": "string"
            },
            "title": "Variables",
            "type": "array"
          }
        },
        "required": [
          "id",
          "notification_type_key",
          "branding_key",
          "language",
          "variables",
          "title",
          "body"
        ],
        "title": "InboxTemplateResponse",
        "type": "object"
      },
      "InvitationPreviewResponse": {
        "description": "What the accept page shows before acceptance: which account + role, and\nwhether the invited email already has a user (so the console knows to ask for\na password vs. prompt sign-in). Served for a valid pending token only.\n\n`tenant_id` is included so the console can label the account it auto-logs the\ninvitee into after acceptance (the invitee is joining it \u2014 not sensitive).",
        "properties": {
          "email": {
            "title": "Email",
            "type": "string"
          },
          "expired": {
            "title": "Expired",
            "type": "boolean"
          },
          "role": {
            "title": "Role",
            "type": "string"
          },
          "tenant_id": {
            "title": "Tenant Id",
            "type": "string"
          },
          "tenant_name": {
            "title": "Tenant Name",
            "type": "string"
          },
          "user_exists": {
            "title": "User Exists",
            "type": "boolean"
          }
        },
        "required": [
          "tenant_id",
          "email",
          "tenant_name",
          "role",
          "expired",
          "user_exists"
        ],
        "title": "InvitationPreviewResponse",
        "type": "object"
      },
      "InvitationResponse": {
        "description": "A pending invitation, for the account's members/invites screen.",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "email": {
            "title": "Email",
            "type": "string"
          },
          "expires_at": {
            "format": "date-time",
            "title": "Expires At",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "role": {
            "title": "Role",
            "type": "string"
          },
          "status": {
            "title": "Status",
            "type": "string"
          }
        },
        "required": [
          "id",
          "email",
          "role",
          "status",
          "expires_at",
          "created_at"
        ],
        "title": "InvitationResponse",
        "type": "object"
      },
      "InviteMemberRequest": {
        "description": "Invite someone to the account with a role. `role` must be\nadmin/member/viewer \u2014 owner is rejected (422).",
        "properties": {
          "email": {
            "title": "Email",
            "type": "string"
          },
          "role": {
            "title": "Role",
            "type": "string"
          }
        },
        "required": [
          "email",
          "role"
        ],
        "title": "InviteMemberRequest",
        "type": "object"
      },
      "IssueApiKeyRequest": {
        "additionalProperties": false,
        "properties": {
          "name": {
            "maxLength": 120,
            "minLength": 1,
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "IssueApiKeyRequest",
        "type": "object"
      },
      "IssuedApiKeyResponse": {
        "description": "Returned ONCE, at creation. `api_key` is the plaintext secret \u2014 it is never\nretrievable again, so the tenant must store it now.",
        "properties": {
          "api_key": {
            "title": "Api Key",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "prefix": {
            "title": "Prefix",
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "prefix",
          "api_key",
          "created_at"
        ],
        "title": "IssuedApiKeyResponse",
        "type": "object"
      },
      "JsonValue": {},
      "LoginRequest": {
        "properties": {
          "email": {
            "title": "Email",
            "type": "string"
          },
          "password": {
            "maxLength": 1024,
            "title": "Password",
            "type": "string"
          }
        },
        "required": [
          "email",
          "password"
        ],
        "title": "LoginRequest",
        "type": "object"
      },
      "MailgunRegion": {
        "description": "Mailgun hosts accounts in one of two regions with different API base URLs.\nStored as the region name; the URL mapping is the sending adapter's concern.",
        "enum": [
          "us",
          "eu"
        ],
        "title": "MailgunRegion",
        "type": "string"
      },
      "MailgunTransportInput": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "title": "Api Key",
            "type": "string"
          },
          "domain": {
            "examples": [
              "mg.acme.com"
            ],
            "title": "Domain",
            "type": "string"
          },
          "region": {
            "default": "us",
            "enum": [
              "us",
              "eu"
            ],
            "title": "Region",
            "type": "string"
          }
        },
        "required": [
          "api_key",
          "domain"
        ],
        "title": "MailgunTransportInput",
        "type": "object"
      },
      "MailgunTransportView": {
        "properties": {
          "domain": {
            "title": "Domain",
            "type": "string"
          },
          "has_api_key": {
            "title": "Has Api Key",
            "type": "boolean"
          },
          "region": {
            "$ref": "#/components/schemas/MailgunRegion"
          }
        },
        "required": [
          "domain",
          "region",
          "has_api_key"
        ],
        "title": "MailgunTransportView",
        "type": "object"
      },
      "MemberResponse": {
        "description": "One current member of an account (email + role).",
        "properties": {
          "email": {
            "title": "Email",
            "type": "string"
          },
          "is_default": {
            "title": "Is Default",
            "type": "boolean"
          },
          "role": {
            "title": "Role",
            "type": "string"
          },
          "user_id": {
            "title": "User Id",
            "type": "string"
          }
        },
        "required": [
          "user_id",
          "email",
          "role",
          "is_default"
        ],
        "title": "MemberResponse",
        "type": "object"
      },
      "NotificationAcceptedResponse": {
        "description": "202 response: one event was recorded per recipient and will be delivered\nasynchronously. `events` maps each recipient to its event id so the tenant\ncan correlate and query per-recipient delivery status.",
        "properties": {
          "events": {
            "items": {
              "$ref": "#/components/schemas/AcceptedEvent"
            },
            "title": "Events",
            "type": "array"
          }
        },
        "required": [
          "events"
        ],
        "title": "NotificationAcceptedResponse",
        "type": "object"
      },
      "NotificationEventStatusResponse": {
        "description": "Delivery status of a triggered event. `status` is pending/processed/failed;\n`error` is the failure reason (whole-event) or a per-channel failure summary on\nan otherwise-processed event (None when every enabled channel succeeded).\n`notes` is non-failure diagnostics (e.g. the named brand didn't resolve, so the\ndefault was used) \u2014 present even on a fully-successful delivery.",
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error"
          },
          "event_id": {
            "title": "Event Id",
            "type": "string"
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes"
          },
          "processed_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Processed At"
          },
          "redacted": {
            "default": false,
            "description": "True once the recipient was erased and this event's personal data was removed. `error` and `notes` are then always null, because both quote the recipient \u2014 without this flag an integration polling a failed event would see the reason vanish and read it as a bug. A `failed` status on a redacted event may mean the trigger was cancelled by the erasure rather than that delivery failed.",
            "title": "Redacted",
            "type": "boolean"
          },
          "status": {
            "$ref": "#/components/schemas/EventStatus"
          }
        },
        "required": [
          "event_id",
          "status",
          "error",
          "notes",
          "created_at",
          "processed_at"
        ],
        "title": "NotificationEventStatusResponse",
        "type": "object"
      },
      "NotificationResponse": {
        "properties": {
          "body": {
            "title": "Body",
            "type": "string"
          },
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "is_read": {
            "title": "Is Read",
            "type": "boolean"
          },
          "notification_type_key": {
            "title": "Notification Type Key",
            "type": "string"
          },
          "read_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Read At"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "id",
          "notification_type_key",
          "title",
          "body",
          "created_at",
          "read_at",
          "is_read"
        ],
        "title": "NotificationResponse",
        "type": "object"
      },
      "NotificationTypeResponse": {
        "properties": {
          "allows_opt_out": {
            "title": "Allows Opt Out",
            "type": "boolean"
          },
          "channel_defaults": {
            "additionalProperties": {
              "type": "boolean"
            },
            "propertyNames": {
              "$ref": "#/components/schemas/Channel"
            },
            "title": "Channel Defaults",
            "type": "object"
          },
          "is_deleted": {
            "title": "Is Deleted",
            "type": "boolean"
          },
          "key": {
            "title": "Key",
            "type": "string"
          },
          "variables": {
            "items": {
              "type": "string"
            },
            "title": "Variables",
            "type": "array"
          }
        },
        "required": [
          "key",
          "channel_defaults",
          "variables",
          "allows_opt_out",
          "is_deleted"
        ],
        "title": "NotificationTypeResponse",
        "type": "object"
      },
      "PasswordResetTokenStatusResponse": {
        "description": "Whether a reset link is still usable, so the console can say so before the\nuser types a new password. Deliberately carries nothing about the account: an\nunknown token and an expired one look identical.",
        "properties": {
          "valid": {
            "title": "Valid",
            "type": "boolean"
          }
        },
        "required": [
          "valid"
        ],
        "title": "PasswordResetTokenStatusResponse",
        "type": "object"
      },
      "PhoneValueRequest": {
        "additionalProperties": false,
        "properties": {
          "value": {
            "examples": [
              "+15551234567"
            ],
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "value"
        ],
        "title": "PhoneValueRequest",
        "type": "object"
      },
      "Plan": {
        "description": "A subscription tier. The natural identity of a plan is its slug; the price\nlives in Paddle (per price id), and the *limits* live in this module's\n`PLAN_LIMITS` so a pricing change is a one-line edit, not a data migration.",
        "enum": [
          "free",
          "pro",
          "business",
          "scale"
        ],
        "title": "Plan",
        "type": "string"
      },
      "PlanChangeDueNow": {
        "description": "What confirming would charge (or credit) immediately. `action` is\nPaddle's vocabulary (`charge`/`credit`); `amount` is minor units.",
        "properties": {
          "action": {
            "title": "Action",
            "type": "string"
          },
          "amount": {
            "title": "Amount",
            "type": "string"
          },
          "currency_code": {
            "title": "Currency Code",
            "type": "string"
          }
        },
        "required": [
          "action",
          "amount",
          "currency_code"
        ],
        "title": "PlanChangeDueNow",
        "type": "object"
      },
      "PlanChangeNextBill": {
        "properties": {
          "amount": {
            "title": "Amount",
            "type": "string"
          },
          "billed_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Billed At"
          },
          "currency_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency Code"
          }
        },
        "required": [
          "amount",
          "currency_code",
          "billed_at"
        ],
        "title": "PlanChangeNextBill",
        "type": "object"
      },
      "PlanChangeQuoteResponse": {
        "description": "The confirmation dialog's content: current tier, target tier, the\nimmediate proration, and (when Paddle supplied it) the next bill.",
        "properties": {
          "current": {
            "$ref": "#/components/schemas/TierResponse"
          },
          "current_period_end": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Period End"
          },
          "due_now": {
            "$ref": "#/components/schemas/PlanChangeDueNow"
          },
          "next_bill": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PlanChangeNextBill"
              },
              {
                "type": "null"
              }
            ]
          },
          "target": {
            "$ref": "#/components/schemas/TierResponse"
          }
        },
        "required": [
          "current",
          "current_period_end",
          "target",
          "due_now",
          "next_bill"
        ],
        "title": "PlanChangeQuoteResponse",
        "type": "object"
      },
      "PlanLimitsResponse": {
        "properties": {
          "included_active_contacts": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Included Active Contacts"
          },
          "max_brands": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Brands"
          }
        },
        "required": [
          "included_active_contacts",
          "max_brands"
        ],
        "title": "PlanLimitsResponse",
        "type": "object"
      },
      "Platform": {
        "description": "The device platform a subscription targets. Optional metadata \u2014 used for\npayload shaping once the push channel lands (APNs, Android and Web bodies\ndiffer), never for routing (that is `PushProvider`'s job).",
        "enum": [
          "ios",
          "android",
          "web"
        ],
        "title": "Platform",
        "type": "string"
      },
      "PortalResponse": {
        "properties": {
          "portal_url": {
            "title": "Portal Url",
            "type": "string"
          }
        },
        "required": [
          "portal_url"
        ],
        "title": "PortalResponse",
        "type": "object"
      },
      "PreferenceDTO": {
        "additionalProperties": false,
        "description": "One preference slot: a notification type on a channel, opted in or out.",
        "properties": {
          "channel": {
            "$ref": "#/components/schemas/Channel",
            "examples": [
              "email"
            ]
          },
          "enabled": {
            "title": "Enabled",
            "type": "boolean"
          },
          "notification_type_key": {
            "examples": [
              "order_shipped"
            ],
            "title": "Notification Type Key",
            "type": "string"
          }
        },
        "required": [
          "notification_type_key",
          "channel",
          "enabled"
        ],
        "title": "PreferenceDTO",
        "type": "object"
      },
      "PushProvider": {
        "description": "The service a push subscription is delivered *through* \u2014 the routing key\nthat ties a contact's `PushSubscription` to the tenant's configured\n`PushTransportConfig` and selects which sender adapter delivers it.\n\nCross-cutting vocabulary (like `Channel`): it lives in `shared` because both\n`contact` (the destination side) and `push_transport` / `outbound_push` (the\nsending side) reference the same members, and they must not drift apart.\n\nCovers direct transports (FCM / APNs / Web Push) and aggregators that fan out\nto the native platforms themselves (Expo, OneSignal). Subclassing `str` keeps\nJSON and dict keys clean.",
        "enum": [
          "fcm",
          "apns",
          "expo",
          "onesignal",
          "webpush"
        ],
        "title": "PushProvider",
        "type": "string"
      },
      "PushSubscriptionDTO": {
        "additionalProperties": false,
        "description": "One push destination: the token/subscription id, the provider it routes\nthrough (required \u2014 see PushProvider), and an optional device platform. The\n`provider`/`platform` enums validate membership automatically (bad value ->\n422).\n\nFor `provider: \"webpush\"`, `value` is the browser subscription's `endpoint`\nand `auth`/`p256dh` are its two keys \u2014 i.e. the browser's own\n`PushSubscription.toJSON()` flattened: `{endpoint, keys: {auth, p256dh}}`\nbecomes `{value, auth, p256dh}`. Flattened rather than nested because this\nDTO serves every provider and a `keys` object would be dead weight on the\nfour that address a plain token.",
        "properties": {
          "auth": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "kQm...=="
            ],
            "title": "Auth"
          },
          "p256dh": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "BN1...=="
            ],
            "title": "P256Dh"
          },
          "platform": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Platform"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "android"
            ]
          },
          "provider": {
            "$ref": "#/components/schemas/PushProvider",
            "examples": [
              "fcm"
            ]
          },
          "value": {
            "examples": [
              "fcm-token-abc"
            ],
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "value",
          "provider"
        ],
        "title": "PushSubscriptionDTO",
        "type": "object"
      },
      "PushSubscriptionRequest": {
        "additionalProperties": false,
        "description": "Add-a-single-subscription body: same shape as one item of the collection\n(value + provider + optional platform, plus the Web Push keys).\n\nInput-only, so this is where the registration rule belongs \u2014 the base class\nit extends is also the response shape and must stay permissive enough to\nrender whatever is stored.",
        "properties": {
          "auth": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "kQm...=="
            ],
            "title": "Auth"
          },
          "p256dh": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "BN1...=="
            ],
            "title": "P256Dh"
          },
          "platform": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Platform"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "android"
            ]
          },
          "provider": {
            "$ref": "#/components/schemas/PushProvider",
            "examples": [
              "fcm"
            ]
          },
          "value": {
            "examples": [
              "fcm-token-abc"
            ],
            "title": "Value",
            "type": "string"
          }
        },
        "required": [
          "value",
          "provider"
        ],
        "title": "PushSubscriptionRequest",
        "type": "object"
      },
      "PushTemplateResponse": {
        "properties": {
          "body": {
            "title": "Body",
            "type": "string"
          },
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Branding Key"
          },
          "data": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Data",
            "type": "object"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language"
          },
          "notification_type_key": {
            "title": "Notification Type Key",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "variables": {
            "items": {
              "type": "string"
            },
            "title": "Variables",
            "type": "array"
          }
        },
        "required": [
          "id",
          "notification_type_key",
          "branding_key",
          "language",
          "variables",
          "title",
          "body",
          "data"
        ],
        "title": "PushTemplateResponse",
        "type": "object"
      },
      "PushTransportRequest": {
        "additionalProperties": false,
        "description": "The settings for one provider. Which provider is in the **path**\n(`PUT /v1/push-transport/{provider}`), so it is no longer a body field \u2014 the\nresource identifies itself, and a body/path disagreement can't arise.",
        "properties": {
          "expo": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExpoTransportInput"
              },
              {
                "type": "null"
              }
            ]
          },
          "fcm": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FcmTransportInput"
              },
              {
                "type": "null"
              }
            ]
          },
          "webpush": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WebPushTransportInput"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "title": "PushTransportRequest",
        "type": "object"
      },
      "PushTransportResponse": {
        "description": "One configured transport. The no-config state is now an **empty list**\nfrom GET rather than a `provider: \"none\"` sentinel \u2014 with several transports\npossible per tenant, \"none\" was a statement the singleton shape needed and a\ncollection expresses directly.",
        "properties": {
          "credentials_unreadable": {
            "default": false,
            "description": "This provider has a stored transport whose credentials can no longer be decrypted (the encryption key was rotated), so its settings are absent from this entry. It is NOT the same as being unconfigured: sends through it fail until it is replaced. PUT the provider again with fresh credentials to repair it.",
            "examples": [
              false
            ],
            "title": "Credentials Unreadable",
            "type": "boolean"
          },
          "expo": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExpoTransportView"
              },
              {
                "type": "null"
              }
            ]
          },
          "fcm": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FcmTransportView"
              },
              {
                "type": "null"
              }
            ]
          },
          "provider": {
            "$ref": "#/components/schemas/PushProvider"
          },
          "updated_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At"
          },
          "webpush": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WebPushTransportView"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "provider"
        ],
        "title": "PushTransportResponse",
        "type": "object"
      },
      "RegisterRequest": {
        "properties": {
          "email": {
            "title": "Email",
            "type": "string"
          },
          "password": {
            "title": "Password",
            "type": "string"
          },
          "tenant_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tenant Name"
          }
        },
        "required": [
          "email",
          "password"
        ],
        "title": "RegisterRequest",
        "type": "object"
      },
      "RegisterSenderDomainRequest": {
        "additionalProperties": false,
        "properties": {
          "domain": {
            "examples": [
              "acme.com"
            ],
            "title": "Domain",
            "type": "string"
          },
          "from_local_part": {
            "default": "notifications",
            "examples": [
              "notifications"
            ],
            "title": "From Local Part",
            "type": "string"
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "Acme"
            ],
            "title": "From Name"
          }
        },
        "required": [
          "domain"
        ],
        "title": "RegisterSenderDomainRequest",
        "type": "object"
      },
      "RenameTenantRequest": {
        "description": "Rename an account the signed-in user owns. Blank/whitespace-only is a clean\n422 (mirrors the Tenant domain rule).",
        "properties": {
          "name": {
            "title": "Name",
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "title": "RenameTenantRequest",
        "type": "object"
      },
      "RenderRequest": {
        "additionalProperties": false,
        "description": "Resolve + render one channel's template for a notification type under a\nbrand.\n\nThe brand key is always required. `variables` is the event payload, rendered\nat the top level with the brand under `brand.*` \u2014 the same shape a send uses.\nA preview has no recipient, so `{{ contact.* }}` renders empty here.",
        "properties": {
          "branding_key": {
            "examples": [
              "acme"
            ],
            "title": "Branding Key",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "notification_type_key": {
            "examples": [
              "order_shipped"
            ],
            "title": "Notification Type Key",
            "type": "string"
          },
          "variables": {
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonValue"
            },
            "description": "Values for the template's `{{ slot }}` markers \u2014 the same shape `POST /v1/notifications` takes, so a preview can be built from the payload you would really send. Any JSON: strings, numbers, nested objects, and lists a template repeats over with `{% for %}`.",
            "examples": [
              {
                "lines": [
                  {
                    "amount": "$40.00",
                    "description": "Widget"
                  }
                ],
                "order_id": "1234"
              }
            ],
            "title": "Variables",
            "type": "object"
          }
        },
        "required": [
          "notification_type_key",
          "branding_key"
        ],
        "title": "RenderRequest",
        "type": "object"
      },
      "RenderedEmailResponse": {
        "properties": {
          "body": {
            "title": "Body",
            "type": "string"
          },
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Branding Key"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language"
          },
          "subject": {
            "title": "Subject",
            "type": "string"
          },
          "template_id": {
            "title": "Template Id",
            "type": "string"
          }
        },
        "required": [
          "template_id",
          "branding_key",
          "language",
          "subject",
          "body"
        ],
        "title": "RenderedEmailResponse",
        "type": "object"
      },
      "RequestPasswordResetRequest": {
        "properties": {
          "email": {
            "title": "Email",
            "type": "string"
          }
        },
        "required": [
          "email"
        ],
        "title": "RequestPasswordResetRequest",
        "type": "object"
      },
      "ResendVerificationRequest": {
        "properties": {
          "email": {
            "title": "Email",
            "type": "string"
          }
        },
        "required": [
          "email"
        ],
        "title": "ResendVerificationRequest",
        "type": "object"
      },
      "ResetPasswordRequest": {
        "properties": {
          "password": {
            "maxLength": 1024,
            "title": "Password",
            "type": "string"
          },
          "token": {
            "minLength": 1,
            "title": "Token",
            "type": "string"
          }
        },
        "required": [
          "token",
          "password"
        ],
        "title": "ResetPasswordRequest",
        "type": "object"
      },
      "SendGridTransportInput": {
        "additionalProperties": false,
        "properties": {
          "api_key": {
            "title": "Api Key",
            "type": "string"
          }
        },
        "required": [
          "api_key"
        ],
        "title": "SendGridTransportInput",
        "type": "object"
      },
      "SendGridTransportView": {
        "properties": {
          "has_api_key": {
            "title": "Has Api Key",
            "type": "boolean"
          }
        },
        "required": [
          "has_api_key"
        ],
        "title": "SendGridTransportView",
        "type": "object"
      },
      "SendTestEmailRequest": {
        "additionalProperties": false,
        "properties": {
          "to_address": {
            "examples": [
              "me@acme.com"
            ],
            "title": "To Address",
            "type": "string"
          }
        },
        "required": [
          "to_address"
        ],
        "title": "SendTestEmailRequest",
        "type": "object"
      },
      "SendTestEmailResponse": {
        "properties": {
          "message_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message Id"
          },
          "provider": {
            "title": "Provider",
            "type": "string"
          }
        },
        "required": [
          "provider",
          "message_id"
        ],
        "title": "SendTestEmailResponse",
        "type": "object"
      },
      "SendTestPushRequest": {
        "additionalProperties": false,
        "description": "A destination to probe the tenant's configured transport with.\n\n`token` is the device token for the token-based providers and the browser's\nsubscription `endpoint` for Web Push, which also needs `auth`/`p256dh` \u2014 the\nsame flattening the contact API uses for `PushSubscriptionDTO`, so an operator\ncan paste one subscription into either.",
        "properties": {
          "auth": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "kQm...=="
            ],
            "title": "Auth"
          },
          "p256dh": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "BN1...=="
            ],
            "title": "P256Dh"
          },
          "token": {
            "examples": [
              "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]"
            ],
            "title": "Token",
            "type": "string"
          }
        },
        "required": [
          "token"
        ],
        "title": "SendTestPushRequest",
        "type": "object"
      },
      "SendTestPushResponse": {
        "properties": {
          "provider": {
            "title": "Provider",
            "type": "string"
          },
          "ticket_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ticket Id"
          }
        },
        "required": [
          "provider",
          "ticket_id"
        ],
        "title": "SendTestPushResponse",
        "type": "object"
      },
      "SenderDomainResponse": {
        "properties": {
          "created_at": {
            "format": "date-time",
            "title": "Created At",
            "type": "string"
          },
          "dns_records": {
            "items": {
              "$ref": "#/components/schemas/DnsRecord"
            },
            "title": "Dns Records",
            "type": "array"
          },
          "domain": {
            "title": "Domain",
            "type": "string"
          },
          "from_address": {
            "title": "From Address",
            "type": "string"
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Name"
          },
          "mail_from_domain": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Mail From Domain"
          },
          "status": {
            "$ref": "#/components/schemas/VerificationStatus"
          },
          "verified_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Verified At"
          }
        },
        "required": [
          "domain",
          "status",
          "from_address",
          "from_name",
          "mail_from_domain",
          "dns_records",
          "created_at",
          "verified_at"
        ],
        "title": "SenderDomainResponse",
        "type": "object"
      },
      "SesTransportInput": {
        "additionalProperties": false,
        "properties": {
          "access_key_id": {
            "examples": [
              "AKIAIOSFODNN7EXAMPLE"
            ],
            "title": "Access Key Id",
            "type": "string"
          },
          "region": {
            "examples": [
              "eu-central-1"
            ],
            "title": "Region",
            "type": "string"
          },
          "secret_access_key": {
            "title": "Secret Access Key",
            "type": "string"
          }
        },
        "required": [
          "access_key_id",
          "secret_access_key",
          "region"
        ],
        "title": "SesTransportInput",
        "type": "object"
      },
      "SesTransportView": {
        "properties": {
          "access_key_id": {
            "title": "Access Key Id",
            "type": "string"
          },
          "has_secret_access_key": {
            "title": "Has Secret Access Key",
            "type": "boolean"
          },
          "region": {
            "title": "Region",
            "type": "string"
          }
        },
        "required": [
          "access_key_id",
          "region",
          "has_secret_access_key"
        ],
        "title": "SesTransportView",
        "type": "object"
      },
      "SessionRequest": {
        "description": "Select/switch to an account: mint an access token scoped to this tenant.\n`remember` makes it the user's default account for next login.",
        "properties": {
          "remember": {
            "default": false,
            "title": "Remember",
            "type": "boolean"
          },
          "tenant_id": {
            "minLength": 1,
            "title": "Tenant Id",
            "type": "string"
          }
        },
        "required": [
          "tenant_id"
        ],
        "title": "SessionRequest",
        "type": "object"
      },
      "SetBrandingSenderRequest": {
        "additionalProperties": false,
        "properties": {
          "from_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "hello@acme.com"
            ],
            "title": "From Address"
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "Acme"
            ],
            "title": "From Name"
          }
        },
        "title": "SetBrandingSenderRequest",
        "type": "object"
      },
      "SetBrandingValuesRequest": {
        "additionalProperties": false,
        "properties": {
          "values": {
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "color": "#00f"
              }
            ],
            "title": "Values",
            "type": "object"
          }
        },
        "required": [
          "values"
        ],
        "title": "SetBrandingValuesRequest",
        "type": "object"
      },
      "SetOptOutPolicyRequest": {
        "additionalProperties": false,
        "properties": {
          "allows_opt_out": {
            "examples": [
              false
            ],
            "title": "Allows Opt Out",
            "type": "boolean"
          }
        },
        "required": [
          "allows_opt_out"
        ],
        "title": "SetOptOutPolicyRequest",
        "type": "object"
      },
      "SetVariablesRequest": {
        "additionalProperties": false,
        "properties": {
          "variables": {
            "examples": [
              [
                "first_name",
                "order_id"
              ]
            ],
            "items": {
              "type": "string"
            },
            "title": "Variables",
            "type": "array",
            "uniqueItems": true
          }
        },
        "required": [
          "variables"
        ],
        "title": "SetVariablesRequest",
        "type": "object"
      },
      "SmtpTransportInput": {
        "additionalProperties": false,
        "properties": {
          "host": {
            "examples": [
              "smtp.acme.com"
            ],
            "title": "Host",
            "type": "string"
          },
          "password": {
            "default": "",
            "title": "Password",
            "type": "string"
          },
          "port": {
            "examples": [
              587
            ],
            "title": "Port",
            "type": "integer"
          },
          "use_tls": {
            "default": false,
            "title": "Use Tls",
            "type": "boolean"
          },
          "username": {
            "default": "",
            "title": "Username",
            "type": "string"
          }
        },
        "required": [
          "host",
          "port"
        ],
        "title": "SmtpTransportInput",
        "type": "object"
      },
      "SmtpTransportView": {
        "properties": {
          "has_password": {
            "title": "Has Password",
            "type": "boolean"
          },
          "host": {
            "title": "Host",
            "type": "string"
          },
          "port": {
            "title": "Port",
            "type": "integer"
          },
          "use_tls": {
            "title": "Use Tls",
            "type": "boolean"
          },
          "username": {
            "title": "Username",
            "type": "string"
          }
        },
        "required": [
          "host",
          "port",
          "username",
          "use_tls",
          "has_password"
        ],
        "title": "SmtpTransportView",
        "type": "object"
      },
      "TenantResponse": {
        "description": "One account the signed-in user belongs to (UI: 'account'; code: tenant).",
        "properties": {
          "is_default": {
            "title": "Is Default",
            "type": "boolean"
          },
          "name": {
            "title": "Name",
            "type": "string"
          },
          "role": {
            "title": "Role",
            "type": "string"
          },
          "status": {
            "default": "active",
            "description": "\"active\" or \"archived\". An archived account is hidden from the switcher and can no longer send \u2014 the trigger refuses it and fan-out skips it. Reversible via unarchive; data is retained.",
            "title": "Status",
            "type": "string"
          },
          "tenant_id": {
            "title": "Tenant Id",
            "type": "string"
          }
        },
        "required": [
          "tenant_id",
          "name",
          "role",
          "is_default"
        ],
        "title": "TenantResponse",
        "type": "object"
      },
      "TierResponse": {
        "properties": {
          "period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period"
          },
          "plan": {
            "title": "Plan",
            "type": "string"
          }
        },
        "required": [
          "plan",
          "period"
        ],
        "title": "TierResponse",
        "type": "object"
      },
      "TransportProvider": {
        "description": "Which transport a tenant configured. The platform default is deliberately\n*not* a member: \"use the platform\" is the absence of a config, never a stored\nrow, so there's exactly one representation of the default state.",
        "enum": [
          "smtp",
          "ses",
          "sendgrid",
          "mailgun"
        ],
        "title": "TransportProvider",
        "type": "string"
      },
      "TriggerNotificationRequest": {
        "additionalProperties": false,
        "description": "A tenant triggering an event for one or more recipients (their own\n`external_id`s \u2014 e.g. every subscriber of a resource). One event is recorded\nper recipient, so each fans out, retries, and reports status independently.\nThe branding key is optional \u2014 omit it (or send an unknown one) and fan-out\nfalls back to the tenant's default branding, unless `strict` is set, which\nrejects an unknown one instead. Recorded + accepted (202); channel resolution\n+ delivery happen asynchronously in the fan-out worker.",
        "properties": {
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "acme"
            ],
            "title": "Branding Key"
          },
          "external_ids": {
            "examples": [
              [
                "crm-12345",
                "crm-67890"
              ]
            ],
            "items": {
              "type": "string"
            },
            "maxItems": 100,
            "minItems": 1,
            "title": "External Ids",
            "type": "array"
          },
          "notification_type_key": {
            "examples": [
              "order_shipped"
            ],
            "title": "Notification Type Key",
            "type": "string"
          },
          "secret_variables": {
            "additionalProperties": {
              "type": "string"
            },
            "description": "Values that must reach the recipient but must not be readable back afterwards \u2014 a one-time code, a password-reset link, a signed URL. They fill `{{ slot }}` markers exactly like `variables` and are sent in full, but the activity log shows them masked: the raw value is hidden, and the message body shown there is a second render in which the secret is replaced. Flat strings only (no repeat-block lists), and a name used here must not also appear in `variables`.",
            "examples": [
              {
                "code": "550913"
              }
            ],
            "title": "Secret Variables",
            "type": "object"
          },
          "strict": {
            "default": false,
            "description": "Refuse the trigger rather than substituting a different brand for the one it named. By default a `branding_key` that does not exist falls back to the account's default brand and the send goes out, so a typo cannot stop your mail. With `strict` that same trigger is a **422** and nothing is queued. Covers the branding key only; it is not a general validation mode, and an unknown `notification_type_key` is still accepted here and reported on the event. Leave it off unless you would rather send nothing than send under the wrong brand.",
            "title": "Strict",
            "type": "boolean"
          },
          "variables": {
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonValue"
            },
            "description": "Values for the template's `{{ slot }}` markers. Any JSON is accepted: strings, numbers, booleans, nested objects (read with `{{ order.customer.name }}`) and lists a template repeats over with `{% for line in lines %} \u2026 {% endfor %}` \u2014 invoice lines, order items, digest entries. A name you don't send renders empty rather than failing, and a list you don't send repeats zero times.",
            "examples": [
              {
                "invoice_number": "INV-1042",
                "lines": [
                  {
                    "amount": "$40.00",
                    "description": "Widget",
                    "qty": 2
                  },
                  {
                    "amount": "$80.00",
                    "description": "Gadget",
                    "qty": 1
                  }
                ],
                "total": "$120.00"
              }
            ],
            "title": "Variables",
            "type": "object"
          }
        },
        "required": [
          "notification_type_key",
          "external_ids"
        ],
        "title": "TriggerNotificationRequest",
        "type": "object"
      },
      "TypePreferenceResponse": {
        "description": "One notification type's per-channel preference state for a contact \u2014 the\nunit of the preferences matrix a client renders.\n\n`channels` carries only the channels this type actually has a template for,\nso a client never renders a switch for a channel that could not be delivered.",
        "properties": {
          "channels": {
            "items": {
              "$ref": "#/components/schemas/ChannelPreferenceResponse"
            },
            "title": "Channels",
            "type": "array"
          },
          "notification_type_key": {
            "title": "Notification Type Key",
            "type": "string"
          }
        },
        "required": [
          "notification_type_key",
          "channels"
        ],
        "title": "TypePreferenceResponse",
        "type": "object"
      },
      "UnreadCountResponse": {
        "properties": {
          "unread": {
            "title": "Unread",
            "type": "integer"
          }
        },
        "required": [
          "unread"
        ],
        "title": "UnreadCountResponse",
        "type": "object"
      },
      "UpdateChannelDefaultsRequest": {
        "additionalProperties": false,
        "properties": {
          "channel_defaults": {
            "additionalProperties": {
              "type": "boolean"
            },
            "examples": [
              {
                "email": false
              }
            ],
            "propertyNames": {
              "$ref": "#/components/schemas/Channel"
            },
            "title": "Channel Defaults",
            "type": "object"
          }
        },
        "required": [
          "channel_defaults"
        ],
        "title": "UpdateChannelDefaultsRequest",
        "type": "object"
      },
      "UpdateContactRequest": {
        "additionalProperties": false,
        "description": "Full new desired state of a contact's mutable collections (whole-resource\nPUT) \u2014 each list/map replaces what's stored, it is not a delta.",
        "properties": {
          "attributes": {
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "first_name": "Ada"
              }
            ],
            "title": "Attributes",
            "type": "object"
          },
          "emails": {
            "examples": [
              [
                "a@example.com"
              ]
            ],
            "items": {
              "type": "string"
            },
            "title": "Emails",
            "type": "array"
          },
          "phones": {
            "examples": [
              [
                "+15551234567"
              ]
            ],
            "items": {
              "type": "string"
            },
            "title": "Phones",
            "type": "array"
          },
          "preferences": {
            "items": {
              "$ref": "#/components/schemas/PreferenceDTO"
            },
            "title": "Preferences",
            "type": "array"
          },
          "push_subscriptions": {
            "items": {
              "$ref": "#/components/schemas/PushSubscriptionDTO"
            },
            "title": "Push Subscriptions",
            "type": "array"
          }
        },
        "title": "UpdateContactRequest",
        "type": "object"
      },
      "UpdateEmailTemplateRequest": {
        "additionalProperties": false,
        "properties": {
          "body": {
            "title": "Body",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "subject": {
            "title": "Subject",
            "type": "string"
          }
        },
        "required": [
          "subject",
          "body"
        ],
        "title": "UpdateEmailTemplateRequest",
        "type": "object"
      },
      "UpdateInboxTemplateRequest": {
        "additionalProperties": false,
        "properties": {
          "body": {
            "title": "Body",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "title": {
            "title": "Title",
            "type": "string"
          }
        },
        "required": [
          "title",
          "body"
        ],
        "title": "UpdateInboxTemplateRequest",
        "type": "object"
      },
      "UpdatePushTemplateRequest": {
        "additionalProperties": false,
        "properties": {
          "body": {
            "default": "",
            "title": "Body",
            "type": "string"
          },
          "data": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Data",
            "type": "object"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "title": {
            "default": "",
            "title": "Title",
            "type": "string"
          }
        },
        "title": "UpdatePushTemplateRequest",
        "type": "object"
      },
      "UpdateWebPushTemplateRequest": {
        "additionalProperties": false,
        "properties": {
          "badge": {
            "default": "",
            "examples": [
              "https://example.com/badge.png"
            ],
            "title": "Badge",
            "type": "string"
          },
          "body": {
            "default": "",
            "examples": [
              "It's on its way."
            ],
            "title": "Body",
            "type": "string"
          },
          "data": {
            "additionalProperties": {
              "type": "string"
            },
            "examples": [
              {
                "order_id": "{{ order_id }}"
              }
            ],
            "title": "Data",
            "type": "object"
          },
          "icon": {
            "default": "",
            "examples": [
              "{{ brand.icon_url }}"
            ],
            "title": "Icon",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "examples": [
              "es"
            ],
            "title": "Language"
          },
          "title": {
            "examples": [
              "Your order shipped"
            ],
            "title": "Title",
            "type": "string"
          },
          "url": {
            "default": "",
            "examples": [
              "https://example.com/orders/{{ order_id }}"
            ],
            "title": "Url",
            "type": "string"
          }
        },
        "required": [
          "title"
        ],
        "title": "UpdateWebPushTemplateRequest",
        "type": "object"
      },
      "UserResponse": {
        "properties": {
          "email": {
            "title": "Email",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "tenant_id": {
            "title": "Tenant Id",
            "type": "string"
          }
        },
        "required": [
          "id",
          "email",
          "tenant_id"
        ],
        "title": "UserResponse",
        "type": "object"
      },
      "ValidationError": {
        "properties": {
          "ctx": {
            "title": "Context",
            "type": "object"
          },
          "input": {
            "title": "Input"
          },
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "title": "Location",
            "type": "array"
          },
          "msg": {
            "title": "Message",
            "type": "string"
          },
          "type": {
            "title": "Error Type",
            "type": "string"
          }
        },
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError",
        "type": "object"
      },
      "VerificationStatus": {
        "description": "Where a sender domain is in the SES verification lifecycle. `PENDING` until\nthe tenant adds the DKIM records and SES confirms them; `VERIFIED` once SES will\nsign+send for the domain; `FAILED` if SES gave up (records never appeared).",
        "enum": [
          "pending",
          "verified",
          "failed"
        ],
        "title": "VerificationStatus",
        "type": "string"
      },
      "VerifyEmailRequest": {
        "properties": {
          "token": {
            "minLength": 1,
            "title": "Token",
            "type": "string"
          }
        },
        "required": [
          "token"
        ],
        "title": "VerifyEmailRequest",
        "type": "object"
      },
      "WebPushPublicKeyResponse": {
        "description": "The tenant's VAPID public key, for a browser about to subscribe.\n\nA whole response for one field, because that is the whole question: a browser\ncannot call `pushManager.subscribe()` without this value as its\n`applicationServerKey`. Returned to *contact* tokens, which no other read on\nthis aggregate is \u2014 every other field here is a credential, and this one is\ngenerated in order to be published.",
        "properties": {
          "public_key": {
            "description": "The tenant's VAPID application server public key, base64url-encoded \u2014 pass it to `pushManager.subscribe({ applicationServerKey })`. Absent as a 404 when the tenant has no Web Push transport, i.e. nobody can subscribe to them yet.",
            "examples": [
              "BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkR..."
            ],
            "title": "Public Key",
            "type": "string"
          }
        },
        "required": [
          "public_key"
        ],
        "title": "WebPushPublicKeyResponse",
        "type": "object"
      },
      "WebPushTemplateResponse": {
        "properties": {
          "badge": {
            "title": "Badge",
            "type": "string"
          },
          "body": {
            "title": "Body",
            "type": "string"
          },
          "branding_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Branding Key"
          },
          "data": {
            "additionalProperties": {
              "type": "string"
            },
            "title": "Data",
            "type": "object"
          },
          "icon": {
            "title": "Icon",
            "type": "string"
          },
          "id": {
            "title": "Id",
            "type": "string"
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language"
          },
          "notification_type_key": {
            "title": "Notification Type Key",
            "type": "string"
          },
          "title": {
            "title": "Title",
            "type": "string"
          },
          "url": {
            "title": "Url",
            "type": "string"
          },
          "variables": {
            "items": {
              "type": "string"
            },
            "title": "Variables",
            "type": "array"
          }
        },
        "required": [
          "id",
          "notification_type_key",
          "branding_key",
          "language",
          "variables",
          "title",
          "body",
          "icon",
          "badge",
          "url",
          "data"
        ],
        "title": "WebPushTemplateResponse",
        "type": "object"
      },
      "WebPushTransportInput": {
        "additionalProperties": false,
        "description": "The tenant's VAPID application server keys.\n\nGenerated by the tenant (`npx web-push generate-vapid-keys`, `vapid --gen`),\nnot by a provider console \u2014 Web Push has no account to sign up for. The pair\nis long-lived and **must not be rotated casually**: existing browser\nsubscriptions were created against the public key and stop being deliverable\nif it changes, so a rotation means re-subscribing every browser.",
        "properties": {
          "private_key": {
            "examples": [
              "UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls"
            ],
            "title": "Private Key",
            "type": "string"
          },
          "public_key": {
            "examples": [
              "BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkR..."
            ],
            "title": "Public Key",
            "type": "string"
          },
          "subject": {
            "examples": [
              "mailto:ops@example.com"
            ],
            "title": "Subject",
            "type": "string"
          }
        },
        "required": [
          "public_key",
          "private_key",
          "subject"
        ],
        "title": "WebPushTransportInput",
        "type": "object"
      },
      "WebPushTransportView": {
        "description": "The public half is returned in full, deliberately: the console has to hand\nit to the browser as `applicationServerKey` for `pushManager.subscribe()`, and\nit is a public key. Only the private half is reduced to a `has_` boolean.",
        "properties": {
          "has_private_key": {
            "title": "Has Private Key",
            "type": "boolean"
          },
          "public_key": {
            "title": "Public Key",
            "type": "string"
          },
          "subject": {
            "title": "Subject",
            "type": "string"
          }
        },
        "required": [
          "public_key",
          "subject",
          "has_private_key"
        ],
        "title": "WebPushTransportView",
        "type": "object"
      }
    }
  },
  "info": {
    "contact": {
      "name": "Elaan",
      "url": "https://elaan.io"
    },
    "description": "The Elaan API: one call delivers a notification to an in-app inbox, email and push.\n\nThis document is the union of every deployment profile, so a given deployment serves a subset of it: the hosted product does not expose the single-tenant routes, and a self-hosted install does not expose billing or sender domains.\n\nDocs: https://elaan.io/docs.html",
    "license": {
      "name": "Proprietary",
      "url": "https://elaan.io/terms.html"
    },
    "summary": "One call delivers a notification to an in-app inbox, email and push.",
    "title": "Elaan API",
    "version": "0.1.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/health": {
      "get": {
        "operationId": "root_health_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Root"
      }
    },
    "/v1/api-keys": {
      "get": {
        "operationId": "list_api_keys_v1_api_keys_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/ApiKeyResponse"
                  },
                  "title": "Response List Api Keys V1 Api Keys Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Api Keys",
        "tags": [
          "api-keys"
        ]
      },
      "post": {
        "operationId": "issue_api_key_v1_api_keys_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IssueApiKeyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssuedApiKeyResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Issue Api Key",
        "tags": [
          "api-keys"
        ]
      }
    },
    "/v1/api-keys/{api_key_id}": {
      "delete": {
        "operationId": "revoke_api_key_v1_api_keys__api_key_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "api_key_id",
            "required": true,
            "schema": {
              "title": "Api Key Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "API key not found"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Revoke Api Key",
        "tags": [
          "api-keys"
        ]
      }
    },
    "/v1/auth/invitations/{token}": {
      "get": {
        "description": "Public: what the accept page shows before acceptance. Only resolves a\n*pending* token (a used/revoked one is a 404, so a spent link leaks nothing).\n`user_exists` tells the console whether to ask for a password (new user) or\nprompt sign-in (existing user).",
        "operationId": "preview_invitation_v1_auth_invitations__token__get",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvitationPreviewResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No valid pending invitation for this token"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Preview Invitation",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/invitations/{token}/accept": {
      "post": {
        "description": "Accept an invite as a brand-new user (unauthenticated \u2014 the emailed token is\nthe proof of address control). Creates an already-verified user + their\nmembership + marks the invite accepted, all in the one request transaction,\nthen auto-logs-in (token scoped to the joined tenant, set as their default).\nIf a user already exists for the email, it's a 409 \u2192 use the sign-in flow.",
        "operationId": "accept_invitation_as_new_user_v1_auth_invitations__token__accept_post",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptInvitationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessTokenResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No such invitation"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Already accepted/revoked, or a tenant exists for this email"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Expired invitation, or a too-short password"
          }
        },
        "summary": "Accept Invitation As New User",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/invitations/{token}/accept-existing": {
      "post": {
        "description": "Accept an invite as an already-registered user who is signed in (the\n'log-in-first' path). The signed-in user must BE the invited address. Adds the\nmembership (not their default \u2014 they keep the tenant they were in) + marks the\ninvite accepted, then mints a token switched into the joined tenant.",
        "operationId": "accept_invitation_as_existing_user_v1_auth_invitations__token__accept_existing_post",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessTokenResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "This invite was sent to a different email"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No such invitation"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Already accepted/revoked, or already a member"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Expired invitation"
          }
        },
        "summary": "Accept Invitation As Existing User",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/login": {
      "post": {
        "operationId": "login_v1_auth_login_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessTokenResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Invalid email or password"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Login",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/password-reset": {
      "post": {
        "description": "Start a password reset. **Always** 202, whether or not the address has an\naccount \u2014 the response must not reveal that, and neither must the timing of a\nmail arriving, which is why the send happens post-response like the others.\nRe-requesting inside the cooldown is also a silent no-op.",
        "operationId": "request_password_reset_v1_auth_password_reset_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequestPasswordResetRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Request Password Reset V1 Auth Password Reset Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Request Password Reset",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/password-reset/confirm": {
      "post": {
        "description": "Redeem the link and set the new password. The link is consumed on success,\nso a second POST 422s. Note existing access tokens are NOT revoked \u2014 they are\nstateless and stay valid until they expire; see CLAUDE.md.",
        "operationId": "confirm_password_reset_v1_auth_password_reset_confirm_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetPasswordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Invalid or expired reset link, or a weak password"
          }
        },
        "summary": "Confirm Password Reset",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/password-reset/{token}": {
      "get": {
        "description": "Is this reset link still usable? Lets the console say \"this link expired\"\nbefore the user types a new password, rather than after. Returns only a\nboolean \u2014 an unknown token and an expired one are indistinguishable, so this\nreveals nothing an attacker holding the token doesn't already have.",
        "operationId": "check_password_reset_token_v1_auth_password_reset__token__get",
        "parameters": [
          {
            "in": "path",
            "name": "token",
            "required": true,
            "schema": {
              "title": "Token",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasswordResetTokenStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Check Password Reset Token",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/register": {
      "post": {
        "operationId": "register_v1_auth_register_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Email already registered, or signup is closed (single-tenant)"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Malformed email, too-short password, or blank/over-long tenant name"
          }
        },
        "summary": "Register",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/resend-verification": {
      "post": {
        "description": "Re-send the verification email. Always 202 (never reveals whether the email\nexists or is already verified); only actually sends for an unverified user.",
        "operationId": "resend_verification_v1_auth_resend_verification_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResendVerificationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Resend Verification V1 Auth Resend Verification Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Resend Verification",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/session": {
      "post": {
        "description": "Select or switch to a tenant: verify the user's membership and mint an\naccess token scoped to that tenant. `remember` sets it as their default.",
        "operationId": "start_session_v1_auth_session_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessTokenResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not a member of that tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Start Session",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/tenants": {
      "get": {
        "description": "The tenants the signed-in user belongs to \u2014 for the tenant picker /\nswitcher. Any valid token identifies the user; the tenants come from their\nmemberships, not from the token's current tenant.",
        "operationId": "list_tenants_v1_auth_tenants_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/TenantResponse"
                  },
                  "title": "Response List Tenants V1 Auth Tenants Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Tenants",
        "tags": [
          "auth",
          "auth"
        ]
      },
      "post": {
        "description": "Create a new tenant owned by the signed-in user. Like signup, the\nroute coordinates single-aggregate use cases in the one request transaction:\nthe Tenant, the owner's Membership (NOT their default \u2014 they keep the tenant\nthey're in; switch explicitly via POST /auth/session), and the tenant's\nun-deletable default brand (every tenant has exactly one). Refused on a\nsingle-tenant (on-prem) install, which is pinned to one tenant.",
        "operationId": "create_tenant_v1_auth_tenants_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTenantRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Tenant creation is disabled (single-tenant install)"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Blank or over-long tenant name"
          }
        },
        "summary": "Create Tenant",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/tenants/{tenant_id}": {
      "patch": {
        "description": "Rename a tenant the signed-in user owns. Authorization is by membership\n(not the token's active tenant), so a user can rename any tenant they own \u2014\ne.g. from the switcher \u2014 without switching into it first. Owner-only (every\nmembership is OWNER today; the check future-proofs for other roles).",
        "operationId": "rename_tenant_v1_auth_tenants__tenant_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenameTenantRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not a member, or not the owner, of that tenant"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No such tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Blank or over-long tenant name"
          }
        },
        "summary": "Rename Tenant",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/tenants/{tenant_id}/archive": {
      "post": {
        "description": "Archive (deactivate) a tenant the signed-in user owns: it's hidden from\nthe switcher and can no longer send (the trigger refuses, fan-out skips).\nReversible via unarchive; data is retained.",
        "operationId": "archive_tenant_v1_auth_tenants__tenant_id__archive_post",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not a member, or not the owner, of that tenant"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No such tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Archive Tenant",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/tenants/{tenant_id}/data-requests": {
      "post": {
        "description": "Ask us to export or delete this tenant's data.\n\n**Owner only.** Deleting a tenant is not an administrative chore, it ends the\nrelationship \u2014 so this uses the same gate as rename/archive rather than the\nadmin+ gate that covers member management. An admin can invite people; only\nan owner can ask for the tenant to be erased.",
        "operationId": "submit_data_request_v1_auth_tenants__tenant_id__data_requests_post",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DataRequestBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataRequestResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not a member, or not the owner, of that tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          },
          "503": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Could not be filed; the caller should email support instead"
          }
        },
        "summary": "Submit Data Request",
        "tags": [
          "auth"
        ]
      }
    },
    "/v1/auth/tenants/{tenant_id}/invitations": {
      "get": {
        "description": "The tenant's outstanding (pending) invitations. Admin+ only.",
        "operationId": "list_invitations_v1_auth_tenants__tenant_id__invitations_get",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/InvitationResponse"
                  },
                  "title": "Response List Invitations V1 Auth Tenants  Tenant Id  Invitations Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not an admin (or higher) of that tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Invitations",
        "tags": [
          "auth",
          "auth"
        ]
      },
      "post": {
        "description": "Invite someone to the tenant by email with a role. Admin+ only. Refuses if\nthe email already belongs to a member (nothing to invite) or has a live pending\ninvite. Emits `UserInvited` (post-commit) \u2192 the dogfooded invite email with the\naccept link.",
        "operationId": "invite_member_v1_auth_tenants__tenant_id__invitations_post",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteMemberRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvitationResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not an admin (or higher) of that tenant"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "A live invite for this email exists, or they're already a member"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Malformed email, or a role of owner"
          }
        },
        "summary": "Invite Member",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/tenants/{tenant_id}/invitations/{invitation_id}": {
      "delete": {
        "description": "Cancel a pending invitation. Admin+ only.",
        "operationId": "revoke_invitation_v1_auth_tenants__tenant_id__invitations__invitation_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "invitation_id",
            "required": true,
            "schema": {
              "title": "Invitation Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not an admin (or higher) of that tenant"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No such invitation"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "This invitation is no longer pending"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Revoke Invitation",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/tenants/{tenant_id}/members": {
      "get": {
        "description": "The tenant's current members (email + role). Admin+ only.",
        "operationId": "list_members_v1_auth_tenants__tenant_id__members_get",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/MemberResponse"
                  },
                  "title": "Response List Members V1 Auth Tenants  Tenant Id  Members Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not an admin (or higher) of that tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Members",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/tenants/{tenant_id}/members/{user_id}": {
      "delete": {
        "description": "Remove a member from the tenant (admin+ only; owners only removable by\nowners; never yourself). If the removed membership was that user's default\ntenant and they still belong to others, one of those is promoted to default\nso their next login still resolves a tenant.",
        "operationId": "remove_member_v1_auth_tenants__tenant_id__members__user_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "user_id",
            "required": true,
            "schema": {
              "title": "User Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not an admin of that tenant, or an admin targeting an owner"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "That person is not a member of this tenant"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "You can't remove yourself from here"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Remove Member",
        "tags": [
          "auth",
          "auth"
        ]
      },
      "patch": {
        "description": "Change a member's role (admin+ only; owners only touchable by owners; never\nyourself; never *to* owner).",
        "operationId": "change_member_role_v1_auth_tenants__tenant_id__members__user_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "user_id",
            "required": true,
            "schema": {
              "title": "User Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeMemberRoleRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not an admin of that tenant, or an admin targeting an owner"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "That person is not a member of this tenant"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "You can't change your own membership from here"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "A role of owner (not assignable via a role change)"
          }
        },
        "summary": "Change Member Role",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/tenants/{tenant_id}/unarchive": {
      "post": {
        "description": "Reactivate a previously archived tenant the signed-in user owns.",
        "operationId": "unarchive_tenant_v1_auth_tenants__tenant_id__unarchive_post",
        "parameters": [
          {
            "in": "path",
            "name": "tenant_id",
            "required": true,
            "schema": {
              "title": "Tenant Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not a member, or not the owner, of that tenant"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No such tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Unarchive Tenant",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/auth/verify-email": {
      "post": {
        "description": "Confirm an email from the link's token. Unauthenticated (the token is the\nproof). Idempotent enough: a second click on a consumed token 422s cleanly.",
        "operationId": "verify_email_v1_auth_verify_email_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyEmailRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Invalid or expired verification link"
          }
        },
        "summary": "Verify Email",
        "tags": [
          "auth",
          "auth"
        ]
      }
    },
    "/v1/billing": {
      "get": {
        "operationId": "get_billing_overview_v1_billing_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingOverviewResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Billing Overview",
        "tags": [
          "billing"
        ]
      }
    },
    "/v1/billing/change-plan": {
      "post": {
        "description": "The paid\u2192paid path (Pro\u2194Business, monthly\u2194annual): Paddle swaps the\nexisting subscription's price with immediate proration \u2014 never a second\ncheckout. 202 because the local plan flips only when the resulting\n`subscription.updated` webhook lands; the console polls, like checkout.",
        "operationId": "change_plan_v1_billing_change_plan_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePlanRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Change Plan V1 Billing Change Plan Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No paid subscription to change, or already on that tier"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unknown plan/period, or no price configured for it"
          }
        },
        "summary": "Change Plan",
        "tags": [
          "billing"
        ]
      }
    },
    "/v1/billing/change-plan/preview": {
      "post": {
        "description": "Quote what /change-plan with the same body would do \u2014 Paddle's dry-run\nproration preview, run through the exact admissibility rules of the execute\npath so a shown quote can always be confirmed. Commits nothing.",
        "operationId": "preview_plan_change_v1_billing_change_plan_preview_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangePlanRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanChangeQuoteResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No paid subscription to change, or already on that tier"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unknown plan/period, or no price configured for it"
          }
        },
        "summary": "Preview Plan Change",
        "tags": [
          "billing"
        ]
      }
    },
    "/v1/billing/portal": {
      "post": {
        "operationId": "create_portal_session_v1_billing_portal_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PortalResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The tenant has no billing account yet (Free / never paid)"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Portal Session",
        "tags": [
          "billing"
        ]
      }
    },
    "/v1/brandings": {
      "get": {
        "operationId": "list_brandings_v1_brandings_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/BrandingResponse"
                  },
                  "title": "Response List Brandings V1 Brandings Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Brandings",
        "tags": [
          "brandings"
        ]
      },
      "post": {
        "operationId": "create_branding_v1_brandings_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBrandingRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "402": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The plan's brand cap is reached \u2014 upgrade to add more"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "A branding with this key already exists"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Branding",
        "tags": [
          "brandings"
        ]
      }
    },
    "/v1/brandings/{key}": {
      "delete": {
        "operationId": "delete_branding_v1_brandings__key__delete",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No branding with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Branding",
        "tags": [
          "brandings"
        ]
      },
      "get": {
        "operationId": "get_branding_v1_brandings__key__get",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No branding with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Branding",
        "tags": [
          "brandings"
        ]
      }
    },
    "/v1/brandings/{key}/sender": {
      "put": {
        "operationId": "set_branding_sender_v1_brandings__key__sender_put",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetBrandingSenderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No branding with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Branding Sender",
        "tags": [
          "brandings"
        ]
      }
    },
    "/v1/brandings/{key}/values": {
      "put": {
        "operationId": "set_branding_values_v1_brandings__key__values_put",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetBrandingValuesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No branding with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Branding Values",
        "tags": [
          "brandings"
        ]
      }
    },
    "/v1/contacts": {
      "get": {
        "operationId": "list_contacts_v1_contacts_get",
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "maxLength": 200,
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Search"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactPage"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Contacts",
        "tags": [
          "contacts"
        ]
      },
      "post": {
        "operationId": "create_contact_v1_contacts_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "A contact with this external_id already exists"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Contact",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/bulk": {
      "post": {
        "description": "Create or update up to 500 contacts in one call, matched by `external_id`.\n\nReturns **200 with a per-row report**, not 201: a batch is rarely all one\nthing, and a status code cannot say \"4,997 created, 3 rejected\". Each row\nreports created, updated or failed with a reason, so a client can show the\nuser exactly which lines of their file need fixing.\n\nA field omitted from a row is left as it was; a field sent empty is cleared.\nThat is what makes an `external_id,email` file safe to import over contacts\nthat already carry phones and attributes.",
        "operationId": "import_contacts_v1_contacts_bulk_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportContactsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportContactsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Import Contacts",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/tokens": {
      "post": {
        "description": "Mint a short-lived, contact-scoped token for the tenant's backend to hand\nto that contact's browser. Tenant-level only (router gate). The browser then\ncalls the contact-facing endpoints directly, scoped to this contact.",
        "operationId": "issue_contact_token_v1_contacts_tokens_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactTokenRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactTokenResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this external_id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Issue Contact Token",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/{contact_id}": {
      "delete": {
        "description": "Delete a contact and erase their personal data everywhere it was copied.\n\nDeleting the `contacts` row is not enough on its own. Every channel freezes a\n*rendered copy* of the message at enqueue time, so that sending needs no\ntemplate or contact access, and the intake outbox keeps the raw trigger\npayload. None of that is reachable by the foreign key cascade, so a plain\ndelete used to leave the recipient's address, device token and message\ncontent behind indefinitely.\n\nDelivery records are kept but blanked: what was sent, when and with what\noutcome survives, while the personal data in it does not. Anything still\nqueued is cancelled so it can never be delivered.",
        "operationId": "delete_contact_v1_contacts__contact_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Contact",
        "tags": [
          "contacts"
        ]
      },
      "get": {
        "operationId": "get_contact_v1_contacts__contact_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Contact",
        "tags": [
          "contacts"
        ]
      },
      "put": {
        "operationId": "update_contact_v1_contacts__contact_id__put",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Contact",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/{contact_id}/attributes/{key}": {
      "delete": {
        "operationId": "remove_attribute_v1_contacts__contact_id__attributes__key__delete",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Remove Attribute",
        "tags": [
          "contacts"
        ]
      },
      "put": {
        "operationId": "set_attribute_v1_contacts__contact_id__attributes__key__put",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttributeValueRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Attribute",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/{contact_id}/emails": {
      "delete": {
        "operationId": "remove_email_v1_contacts__contact_id__emails_delete",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "value",
            "required": true,
            "schema": {
              "title": "Value",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Remove Email",
        "tags": [
          "contacts"
        ]
      },
      "post": {
        "operationId": "add_email_v1_contacts__contact_id__emails_post",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailValueRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Add Email",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/{contact_id}/language": {
      "put": {
        "description": "Set (or clear, with null) the contact's preferred language \u2014 the contact's\nown choice, so it lives on the self-service router (own-contact-or-403).",
        "operationId": "set_language_v1_contacts__contact_id__language_put",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactLanguageRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Language",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/{contact_id}/notifications": {
      "get": {
        "operationId": "list_notifications_v1_contacts__contact_id__notifications_get",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "unread",
            "required": false,
            "schema": {
              "default": false,
              "title": "Unread",
              "type": "boolean"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/NotificationResponse"
                  },
                  "title": "Response List Notifications V1 Contacts  Contact Id  Notifications Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Notifications",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/contacts/{contact_id}/notifications/read-all": {
      "post": {
        "operationId": "mark_all_read_v1_contacts__contact_id__notifications_read_all_post",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Mark All Read",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/contacts/{contact_id}/notifications/unread-count": {
      "get": {
        "operationId": "unread_count_v1_contacts__contact_id__notifications_unread_count_get",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnreadCountResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Unread Count",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/contacts/{contact_id}/notifications/{notification_id}": {
      "delete": {
        "operationId": "delete_notification_v1_contacts__contact_id__notifications__notification_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "notification_id",
            "required": true,
            "schema": {
              "title": "Notification Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No notification with this id for this contact"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Notification",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/contacts/{contact_id}/notifications/{notification_id}/read": {
      "post": {
        "operationId": "mark_read_v1_contacts__contact_id__notifications__notification_id__read_post",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "notification_id",
            "required": true,
            "schema": {
              "title": "Notification Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No notification with this id for this contact"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Mark Read",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/contacts/{contact_id}/notifications/{notification_id}/unread": {
      "post": {
        "operationId": "mark_unread_v1_contacts__contact_id__notifications__notification_id__unread_post",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "notification_id",
            "required": true,
            "schema": {
              "title": "Notification Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No notification with this id for this contact"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Mark Unread",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/contacts/{contact_id}/phones": {
      "delete": {
        "operationId": "remove_phone_v1_contacts__contact_id__phones_delete",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "value",
            "required": true,
            "schema": {
              "title": "Value",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Remove Phone",
        "tags": [
          "contacts"
        ]
      },
      "post": {
        "operationId": "add_phone_v1_contacts__contact_id__phones_post",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PhoneValueRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Add Phone",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/{contact_id}/preferences": {
      "get": {
        "description": "The contact's whole preference centre in one read: their saved preferred\n`language` plus the notification-type \u00d7 channel matrix (`types`) \u2014 every type\nthey can act on \u00d7 the channels it can reach, with the effective on/off and\nwhether it's an explicit override. Powers a client preferences UI without a\nsecond call. Contact token reads its own; a tenant token reads any contact's.\n\nServed here rather than by `contact` because it composes three aggregates\n(contact, notification_type, channel_template) and `contact` is contractually\nindependent of the template module.\n\nNB: the payload is an object `{language, types}`; `types` is the former\ntop-level array (the `@elaanio/*` SDK's `getPreferences` moved in lockstep).",
        "operationId": "get_contact_preferences_v1_contacts__contact_id__preferences_get",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactPreferencesResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Contact Preferences",
        "tags": [
          "notifications"
        ]
      },
      "put": {
        "operationId": "set_preference_v1_contacts__contact_id__preferences_put",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreferenceDTO"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Preference",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/{contact_id}/preferences/{notification_type_key}/{channel}": {
      "delete": {
        "operationId": "clear_preference_v1_contacts__contact_id__preferences__notification_type_key___channel__delete",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "notification_type_key",
            "required": true,
            "schema": {
              "title": "Notification Type Key",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "channel",
            "required": true,
            "schema": {
              "title": "Channel",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Clear Preference",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/{contact_id}/push-subscriptions": {
      "delete": {
        "operationId": "remove_push_subscription_v1_contacts__contact_id__push_subscriptions_delete",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "value",
            "required": true,
            "schema": {
              "title": "Value",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "provider",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/PushProvider"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Remove Push Subscription",
        "tags": [
          "contacts"
        ]
      },
      "post": {
        "operationId": "add_push_subscription_v1_contacts__contact_id__push_subscriptions_post",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PushSubscriptionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No contact with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The contact was modified concurrently; reload and retry"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Add Push Subscription",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/contacts/{contact_id}/stream": {
      "get": {
        "operationId": "stream_notifications_v1_contacts__contact_id__stream_get",
        "parameters": [
          {
            "in": "path",
            "name": "contact_id",
            "required": true,
            "schema": {
              "title": "Contact Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Stream Notifications",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/deliveries": {
      "get": {
        "operationId": "list_deliveries_v1_deliveries_get",
        "parameters": [
          {
            "description": "Which store to read.",
            "in": "query",
            "name": "channel",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/DeliveryChannel",
              "description": "Which store to read."
            }
          },
          {
            "description": "Repeatable. Values are channel-specific; an unknown one is a 422.",
            "in": "query",
            "name": "status",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "items": {
                    "type": "string"
                  },
                  "type": "array"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Repeatable. Values are channel-specific; an unknown one is a 422.",
              "title": "Status"
            }
          },
          {
            "in": "query",
            "name": "contact_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Contact Id"
            }
          },
          {
            "description": "Event channel only \u2014 the tenant's own recipient reference.",
            "in": "query",
            "name": "external_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Event channel only \u2014 the tenant's own recipient reference.",
              "title": "External Id"
            }
          },
          {
            "in": "query",
            "name": "notification_type",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Notification Type"
            }
          },
          {
            "description": "All rows produced by one trigger.",
            "in": "query",
            "name": "event_id",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "All rows produced by one trigger.",
              "title": "Event Id"
            }
          },
          {
            "in": "query",
            "name": "created_from",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Created From"
            }
          },
          {
            "in": "query",
            "name": "created_to",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "format": "date-time",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Created To"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "offset",
            "required": false,
            "schema": {
              "default": 0,
              "minimum": 0,
              "title": "Offset",
              "type": "integer"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryPage"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Deliveries",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/deliveries/{channel}/{delivery_id}": {
      "get": {
        "description": "One delivery with the message exactly as it went out \u2014 the frozen render,\nnot a re-render from the current template. The body is served only here, never\nin the list, because it is unbounded text.",
        "operationId": "get_delivery_v1_deliveries__channel___delivery_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "channel",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/DeliveryChannel"
            }
          },
          {
            "in": "path",
            "name": "delivery_id",
            "required": true,
            "schema": {
              "title": "Delivery Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryDetail"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No delivery with this id for this tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Delivery",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/email-templates": {
      "get": {
        "operationId": "list_email_templates_v1_email_templates_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/EmailTemplateResponse"
                  },
                  "title": "Response List Email Templates V1 Email Templates Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Email Templates",
        "tags": [
          "email-templates"
        ]
      },
      "post": {
        "operationId": "create_email_template_v1_email_templates_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEmailTemplateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "A template for this notification type + brand already exists"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The keys are malformed, the notification type isn't live, the branding doesn't exist, or the content is empty"
          }
        },
        "summary": "Create Email Template",
        "tags": [
          "email-templates"
        ]
      }
    },
    "/v1/email-templates/affected-by/{notification_type_key}": {
      "get": {
        "description": "Templates for this notification type that reference variables it no longer\nexposes \u2014 the fallout to fix after narrowing/renaming its variables.",
        "operationId": "list_affected_templates_v1_email_templates_affected_by__notification_type_key__get",
        "parameters": [
          {
            "in": "path",
            "name": "notification_type_key",
            "required": true,
            "schema": {
              "title": "Notification Type Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/AffectedTemplateResponse"
                  },
                  "title": "Response List Affected Templates V1 Email Templates Affected By  Notification Type Key  Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The notification_type_key is malformed or doesn't refer to a notification type"
          }
        },
        "summary": "List Affected Templates",
        "tags": [
          "email-templates"
        ]
      }
    },
    "/v1/email-templates/render": {
      "post": {
        "description": "Resolve the brand override (else tenant default) and render it with the\nevent variables merged over the brand's values \u2014 the 'what would we send'\npreview.",
        "operationId": "render_email_v1_email_templates_render_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenderRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderedEmailResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The branding doesn't exist, no template resolves, or the event variables + branding values don't cover every slot"
          }
        },
        "summary": "Render Email",
        "tags": [
          "email-templates"
        ]
      }
    },
    "/v1/email-templates/{template_id}": {
      "delete": {
        "operationId": "delete_email_template_v1_email_templates__template_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No email template with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Email Template",
        "tags": [
          "email-templates"
        ]
      },
      "get": {
        "operationId": "get_email_template_v1_email_templates__template_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No email template with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Email Template",
        "tags": [
          "email-templates"
        ]
      },
      "put": {
        "operationId": "update_email_template_v1_email_templates__template_id__put",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEmailTemplateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No email template with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Another template already occupies this notification type + brand + language slot"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The new content is empty"
          }
        },
        "summary": "Update Email Template",
        "tags": [
          "email-templates"
        ]
      }
    },
    "/v1/email-transport": {
      "delete": {
        "operationId": "delete_email_transport_v1_email_transport_delete",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Email Transport",
        "tags": [
          "email-transport"
        ]
      },
      "get": {
        "operationId": "get_email_transport_v1_email_transport_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTransportResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Email Transport",
        "tags": [
          "email-transport"
        ]
      },
      "put": {
        "operationId": "put_email_transport_v1_email_transport_put",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmailTransportRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailTransportResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Put Email Transport",
        "tags": [
          "email-transport"
        ]
      }
    },
    "/v1/email-transport/test": {
      "post": {
        "operationId": "send_test_email_v1_email_transport_test_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendTestEmailRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendTestEmailResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Send Test Email",
        "tags": [
          "email-transport"
        ]
      }
    },
    "/v1/erasures": {
      "post": {
        "description": "Erase everything held about one recipient, addressed by **your** id for\nthem, whether or not a contact currently exists.\n\n`DELETE /v1/contacts/{id}` covers the ordinary case, but it can only reach\nwhat a live contact points at. A trigger records the recipient by the\n`external_id` you sent, and resolution to a contact happens later, in the\nbackground \u2014 so a typo, an integration that addresses people by email while\nyour contacts are keyed by CRM id, a trigger fired before the contact was\ncreated, or a contact deleted before this endpoint existed all leave trigger\npayloads that no contact delete can reach. Those payloads are the rawest data\nwe hold: your `variables`, plus the external id itself, which is frequently\nan email address.\n\nUse this to answer an erasure request when you are not certain a contact\nexists. It is idempotent, safe to call repeatedly, and returns what it\ntouched so you can evidence the request. If a contact does exist it is\ndeleted too, making this a strict superset of the contact delete.",
        "operationId": "erase_recipient_v1_erasures_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ErasureRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErasureResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Erase Recipient",
        "tags": [
          "contacts"
        ]
      }
    },
    "/v1/inbox-templates": {
      "get": {
        "operationId": "list_inbox_templates_v1_inbox_templates_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/InboxTemplateResponse"
                  },
                  "title": "Response List Inbox Templates V1 Inbox Templates Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Inbox Templates",
        "tags": [
          "inbox-templates"
        ]
      },
      "post": {
        "operationId": "create_inbox_template_v1_inbox_templates_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxTemplateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboxTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "A template for this notification type + brand already exists"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The keys are malformed, the notification type isn't live, the branding doesn't exist, or the content is empty"
          }
        },
        "summary": "Create Inbox Template",
        "tags": [
          "inbox-templates"
        ]
      }
    },
    "/v1/inbox-templates/{template_id}": {
      "delete": {
        "operationId": "delete_inbox_template_v1_inbox_templates__template_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No inbox template with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Inbox Template",
        "tags": [
          "inbox-templates"
        ]
      },
      "get": {
        "operationId": "get_inbox_template_v1_inbox_templates__template_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboxTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No inbox template with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Inbox Template",
        "tags": [
          "inbox-templates"
        ]
      },
      "put": {
        "operationId": "update_inbox_template_v1_inbox_templates__template_id__put",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateInboxTemplateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboxTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No inbox template with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Another template already occupies this notification type + brand + language slot"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The new content is empty"
          }
        },
        "summary": "Update Inbox Template",
        "tags": [
          "inbox-templates"
        ]
      }
    },
    "/v1/meta": {
      "get": {
        "description": "Deployment capabilities + build version. Public (like /health): the\nconsole reads it before rendering nav to hide features this profile\ndoesn't offer.\n\n`registration_open` is the one dynamic capability \u2014 a single-tenant\ninstall starts open and closes permanently once its tenant is claimed.\nMulti-tenant installs answer it as a constant, without a DB read.\n\n`account_creation_open` mirrors the backend rule that a single-tenant\n(on-prem) install is pinned to one account (POST /auth/tenants is 403\nthere): the console reads it to hide \"Create new account\".\n\n`data_requests` reports whether we operate this deployment on the\ntenant's behalf, and so whether asking us to export or erase their data\nmeans anything. Off on-prem, where they hold the database themselves.",
        "operationId": "meta_v1_meta_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Meta V1 Meta Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Meta"
      }
    },
    "/v1/notification-types": {
      "get": {
        "operationId": "list_notification_types_v1_notification_types_get",
        "parameters": [
          {
            "in": "query",
            "name": "include_deleted",
            "required": false,
            "schema": {
              "default": false,
              "title": "Include Deleted",
              "type": "boolean"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/NotificationTypeResponse"
                  },
                  "title": "Response List Notification Types V1 Notification Types Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Notification Types",
        "tags": [
          "notification-types"
        ]
      },
      "post": {
        "operationId": "create_notification_type_v1_notification_types_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateNotificationTypeRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationTypeResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "A live notification type with this key already exists"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Create Notification Type",
        "tags": [
          "notification-types"
        ]
      }
    },
    "/v1/notification-types/{key}": {
      "delete": {
        "operationId": "delete_notification_type_v1_notification_types__key__delete",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No notification type with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Notification Type",
        "tags": [
          "notification-types"
        ]
      },
      "get": {
        "operationId": "get_notification_type_v1_notification_types__key__get",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationTypeResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No notification type with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Notification Type",
        "tags": [
          "notification-types"
        ]
      }
    },
    "/v1/notification-types/{key}/channel-defaults": {
      "patch": {
        "operationId": "update_channel_defaults_v1_notification_types__key__channel_defaults_patch",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateChannelDefaultsRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationTypeResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No notification type with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Update Channel Defaults",
        "tags": [
          "notification-types"
        ]
      }
    },
    "/v1/notification-types/{key}/opt-out-policy": {
      "patch": {
        "description": "Turn opting out on or off for this type. Turning it OFF leaves existing\ncontact preferences in place but dormant, so turning it back ON restores what\neach contact had chosen.",
        "operationId": "set_opt_out_policy_v1_notification_types__key__opt_out_policy_patch",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetOptOutPolicyRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationTypeResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No notification type with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Opt Out Policy",
        "tags": [
          "notification-types"
        ]
      }
    },
    "/v1/notification-types/{key}/restore": {
      "post": {
        "operationId": "restore_notification_type_v1_notification_types__key__restore_post",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationTypeResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No notification type with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Restore Notification Type",
        "tags": [
          "notification-types"
        ]
      }
    },
    "/v1/notification-types/{key}/variables": {
      "put": {
        "operationId": "set_variables_v1_notification_types__key__variables_put",
        "parameters": [
          {
            "in": "path",
            "name": "key",
            "required": true,
            "schema": {
              "title": "Key",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetVariablesRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationTypeResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No notification type with this key"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Set Variables",
        "tags": [
          "notification-types"
        ]
      }
    },
    "/v1/notifications": {
      "post": {
        "description": "The tenant front door: record one triggered event per recipient and accept\n(202). The request does no per-channel work \u2014 channel resolution, rendering\nand delivery happen asynchronously in the fan-out worker, so one channel's\n(or one recipient's) failure can't roll back another. Each recipient's\n`event_id` correlates its accepted event for status.\n\nAn archived account can't send: reject up front (403) rather than record\nevents that fan-out would only skip. (A None tenant \u2014 a tenant_id that\nauthenticated but has no row \u2014 is a data-integrity impossibility, not an\narchived account, so it's deliberately allowed through rather than 403'd.)\n\nThe archived check runs *before* the idempotency replay deliberately: an\narchived account gets the same 403 whether or not it happens to be resending\na token, rather than one answer for a fresh trigger and another for a retry.",
        "operationId": "trigger_notification_v1_notifications_post",
        "parameters": [
          {
            "description": "Optional dedupe token for this request. Send the same token again and the original event ids come back without sending anything a second time \u2014 for callers driven by an at-least-once source (a queue, a webhook, a retried job), where a redelivery is routine. Reusing a token for a *different* payload is a 409. Scoped to your account, at most 255 characters.",
            "in": "header",
            "name": "Idempotency-Key",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Optional dedupe token for this request. Send the same token again and the original event ids come back without sending anything a second time \u2014 for callers driven by an at-least-once source (a queue, a webhook, a retried job), where a redelivery is routine. Reusing a token for a *different* payload is a 409. Scoped to your account, at most 255 characters.",
              "title": "Idempotency-Key"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TriggerNotificationRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationAcceptedResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The Idempotency-Key was already used for a request with a different payload (permanent \u2014 use a new key), or a concurrent copy of this same request is holding it (transient \u2014 retry for the replay)"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Trigger Notification",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/notifications/{event_id}": {
      "get": {
        "description": "Delivery status of a previously-triggered event: pending / processed /\nfailed, plus any per-channel error summary and the processing timestamp.",
        "operationId": "notification_event_status_v1_notifications__event_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "event_id",
            "required": true,
            "schema": {
              "title": "Event Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationEventStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No triggered event with this id for this tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Notification Event Status",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/notifications/{event_id}/deliveries": {
      "get": {
        "description": "Every channel's outcome for one trigger. Unpaged by design \u2014 one event\nproduces a handful of rows, so this is a bounded fan-in, not a scan.",
        "operationId": "event_deliveries_v1_notifications__event_id__deliveries_get",
        "parameters": [
          {
            "in": "path",
            "name": "event_id",
            "required": true,
            "schema": {
              "title": "Event Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventDeliveriesResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No event with this id for this tenant"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Event Deliveries",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/push-templates": {
      "get": {
        "operationId": "list_push_templates_v1_push_templates_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/PushTemplateResponse"
                  },
                  "title": "Response List Push Templates V1 Push Templates Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Push Templates",
        "tags": [
          "push-templates"
        ]
      },
      "post": {
        "operationId": "create_push_template_v1_push_templates_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePushTemplateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "A template for this notification type + brand already exists"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The keys are malformed, the notification type isn't live, the branding doesn't exist, or the content is empty"
          }
        },
        "summary": "Create Push Template",
        "tags": [
          "push-templates"
        ]
      }
    },
    "/v1/push-templates/{template_id}": {
      "delete": {
        "operationId": "delete_push_template_v1_push_templates__template_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No push template with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Push Template",
        "tags": [
          "push-templates"
        ]
      },
      "get": {
        "operationId": "get_push_template_v1_push_templates__template_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No push template with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Push Template",
        "tags": [
          "push-templates"
        ]
      },
      "put": {
        "operationId": "update_push_template_v1_push_templates__template_id__put",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePushTemplateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No push template with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Another template already occupies this notification type + brand + language slot"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The new content is empty"
          }
        },
        "summary": "Update Push Template",
        "tags": [
          "push-templates"
        ]
      }
    },
    "/v1/push-transport": {
      "get": {
        "description": "Every transport this tenant has configured. An empty list means they can't\nsend push at all \u2014 there is no platform default, so that is a real answer\nrather than a 404.\n\nAn entry with `credentials_unreadable` is configured but unusable (the\nencryption key was rotated). It is listed rather than hidden so the state is\ndistinguishable from \"never set up\", which is what it silently looked like\nbefore \u2014 while every send through it kept failing.",
        "operationId": "list_push_transports_v1_push_transport_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/PushTransportResponse"
                  },
                  "title": "Response List Push Transports V1 Push Transport Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Push Transports",
        "tags": [
          "push-transport"
        ]
      }
    },
    "/v1/push-transport/{provider}": {
      "delete": {
        "operationId": "delete_push_transport_v1_push_transport__provider__delete",
        "parameters": [
          {
            "in": "path",
            "name": "provider",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/PushProvider"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Push Transport",
        "tags": [
          "push-transport"
        ]
      },
      "put": {
        "description": "Replace one provider's transport. Only that provider's entry is touched.",
        "operationId": "put_push_transport_v1_push_transport__provider__put",
        "parameters": [
          {
            "in": "path",
            "name": "provider",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/PushProvider"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PushTransportRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PushTransportResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The provider has no adapter yet, or its settings are malformed"
          }
        },
        "summary": "Put Push Transport",
        "tags": [
          "push-transport"
        ]
      }
    },
    "/v1/push-transport/{provider}/test": {
      "post": {
        "operationId": "send_test_push_v1_push_transport__provider__test_post",
        "parameters": [
          {
            "in": "path",
            "name": "provider",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/PushProvider"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendTestPushRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendTestPushResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Send Test Push",
        "tags": [
          "push-transport"
        ]
      }
    },
    "/v1/sender-domains": {
      "get": {
        "operationId": "list_sender_domains_v1_sender_domains_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/SenderDomainResponse"
                  },
                  "title": "Response List Sender Domains V1 Sender Domains Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Sender Domains",
        "tags": [
          "sender-domains"
        ]
      },
      "post": {
        "operationId": "register_sender_domain_v1_sender_domains_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterSenderDomainRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SenderDomainResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "This domain is already registered"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Register Sender Domain",
        "tags": [
          "sender-domains"
        ]
      }
    },
    "/v1/sender-domains/{domain}": {
      "delete": {
        "operationId": "delete_sender_domain_v1_sender_domains__domain__delete",
        "parameters": [
          {
            "in": "path",
            "name": "domain",
            "required": true,
            "schema": {
              "title": "Domain",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No sender domain with this name"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Sender Domain",
        "tags": [
          "sender-domains"
        ]
      },
      "get": {
        "operationId": "get_sender_domain_v1_sender_domains__domain__get",
        "parameters": [
          {
            "in": "path",
            "name": "domain",
            "required": true,
            "schema": {
              "title": "Domain",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SenderDomainResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No sender domain with this name"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Sender Domain",
        "tags": [
          "sender-domains"
        ]
      }
    },
    "/v1/sender-domains/{domain}/refresh": {
      "post": {
        "operationId": "refresh_sender_domain_v1_sender_domains__domain__refresh_post",
        "parameters": [
          {
            "in": "path",
            "name": "domain",
            "required": true,
            "schema": {
              "title": "Domain",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SenderDomainResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No sender domain with this name"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Refresh Sender Domain",
        "tags": [
          "sender-domains"
        ]
      }
    },
    "/v1/stats": {
      "get": {
        "description": "Tenant-wide delivery counts by status across the three outboxes (event\nintake, email, push) \u2014 powers the console dashboard's delivery panel.",
        "operationId": "delivery_stats_v1_stats_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryStatsResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delivery Stats",
        "tags": [
          "notifications"
        ]
      }
    },
    "/v1/web-push-templates": {
      "get": {
        "operationId": "list_web_push_templates_v1_web_push_templates_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/WebPushTemplateResponse"
                  },
                  "title": "Response List Web Push Templates V1 Web Push Templates Get",
                  "type": "array"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "List Web Push Templates",
        "tags": [
          "web-push-templates"
        ]
      },
      "post": {
        "operationId": "create_web_push_template_v1_web_push_templates_post",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebPushTemplateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebPushTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "A template for this notification type + brand already exists"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The keys are malformed, the notification type isn't live, the branding doesn't exist, or the content is empty"
          }
        },
        "summary": "Create Web Push Template",
        "tags": [
          "web-push-templates"
        ]
      }
    },
    "/v1/web-push-templates/{template_id}": {
      "delete": {
        "operationId": "delete_web_push_template_v1_web_push_templates__template_id__delete",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No web-push template with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Delete Web Push Template",
        "tags": [
          "web-push-templates"
        ]
      },
      "get": {
        "operationId": "get_web_push_template_v1_web_push_templates__template_id__get",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebPushTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No web-push template with this id"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Web Push Template",
        "tags": [
          "web-push-templates"
        ]
      },
      "put": {
        "operationId": "update_web_push_template_v1_web_push_templates__template_id__put",
        "parameters": [
          {
            "in": "path",
            "name": "template_id",
            "required": true,
            "schema": {
              "title": "Template Id",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebPushTemplateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebPushTemplateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "No web-push template with this id"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Another template already occupies this notification type + brand + language slot"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "The new content is empty"
          }
        },
        "summary": "Update Web Push Template",
        "tags": [
          "web-push-templates"
        ]
      }
    },
    "/v1/web-push/public-key": {
      "get": {
        "description": "The VAPID public key a browser needs as `applicationServerKey`.\n\nNo path parameter and no role gate: the tenant comes from the verified token\nlike everywhere else, and a contact token (the subscribing browser) resolves\none just as a tenant token (a backend, or the console) does.\n\n404 when the tenant has no Web Push transport \u2014 deliberately not an empty\nstring, which a caller would hand to `subscribe()` and get an opaque browser\nerror instead of \"this account hasn't enabled browser push\".",
        "operationId": "get_web_push_public_key_v1_web_push_public_key_get",
        "parameters": [
          {
            "in": "header",
            "name": "authorization",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Authorization"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebPushPublicKeyResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "This tenant has no Web Push transport configured"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Get Web Push Public Key",
        "tags": [
          "web-push"
        ]
      }
    },
    "/webhooks/paddle": {
      "post": {
        "description": "Verify the signature, normalize the event, and reconcile it onto the\ntenant's subscription. Returns 200 for anything verified (even events we\nignore) so Paddle doesn't redeliver; an unverifiable signature raises \u2192 400.\nThe transactional route commits before responding.\n\nThe raw body goes to the verifier undecoded \u2014 the HMAC covers exactly these\nbytes, and a body that isn't UTF-8 is the verifier's 400 to raise, not an\nunhandled decode error on an anonymous endpoint.",
        "operationId": "paddle_webhook_webhooks_paddle_post",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "title": "Response Paddle Webhook Webhooks Paddle Post",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Paddle Webhook"
      }
    }
  },
  "servers": [
    {
      "description": "Elaan hosted API",
      "url": "https://api.elaan.io"
    },
    {
      "description": "Self-hosted install",
      "url": "https://{host}",
      "variables": {
        "host": {
          "default": "elaan.example.com"
        }
      }
    }
  ]
}
