{
  "openapi": "3.1.0",
  "info": {
    "title": "eusend API",
    "version": "1.0.0",
    "summary": "EU-native transactional and marketing email API.",
    "description": "eusend sends transactional and marketing email from infrastructure that stays inside the European Union — processing, storage and delivery alike.\n\n**When to use this API.** Reach for eusend to send application email from server-side code: password resets, receipts, verification codes, notifications, and opt-in marketing broadcasts to a list you own. It is a good fit when GDPR or EU data residency is a requirement, when you are migrating off Resend, SendGrid, Mailgun, Postmark or SES, or when you need SMTP relay rather than an HTTP call. It is not a fit for inbox hosting, for reading a user’s mailbox, or for sending to purchased or scraped lists.\n\n**Getting started.** Create an account, verify a sending domain by publishing the DNS records the domain endpoints hand back, then `POST /emails`. A key prefixed `eu_test_` exercises the whole pipeline without delivering anything.\n\n**Authentication.** Every authenticated endpoint takes `Authorization: Bearer <key>`. Keys are `eu_live_…` or `eu_test_…`, and carry either `full_access` or the send-only `sending_access` permission.\n\n**Errors.** Non-2xx responses are always `{ \"error\": string, \"code\": string }`. Branch on `code`; the list is enumerated on the `Error` schema.\n\n**Conventions.** Request bodies use snake_case and reject unknown properties. Response bodies use camelCase, except the pagination cursor and a handful of endpoints noted inline. List endpoints are cursor-paginated, newest first. Every response carries `X-Request-Id`.",
    "termsOfService": "https://eusend.dev/legal/terms",
    "contact": {
      "name": "eusend support",
      "email": "support@eusend.dev",
      "url": "https://eusend.dev/support"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://eusend.dev/legal/terms"
    }
  },
  "externalDocs": {
    "description": "eusend documentation",
    "url": "https://eusend.dev/docs"
  },
  "servers": [
    {
      "url": "https://api.eusend.dev",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Emails",
      "description": "Send, schedule, inspect and cancel individual messages."
    },
    {
      "name": "Domains",
      "description": "Register sending domains and verify their DKIM, SPF and DMARC records."
    },
    {
      "name": "API keys",
      "description": "Mint and revoke credentials, including send-only and domain-scoped keys."
    },
    {
      "name": "Audiences",
      "description": "Named contact lists a broadcast can be sent to."
    },
    {
      "name": "Contacts",
      "description": "The people in an audience, and their subscription state."
    },
    {
      "name": "Suppressions",
      "description": "Addresses this organization will not send to."
    },
    {
      "name": "Templates",
      "description": "Stored HTML bodies with variable placeholders."
    },
    {
      "name": "Broadcasts",
      "description": "One message sent to a whole audience."
    },
    {
      "name": "Webhooks",
      "description": "HTTP callbacks for delivery, bounce, complaint, open and click events."
    },
    {
      "name": "System",
      "description": "Unauthenticated liveness and readiness checks."
    }
  ],
  "paths": {
    "/emails": {
      "post": {
        "operationId": "sendEmail",
        "summary": "Send an email",
        "description": "Queues one message for delivery and returns its id immediately. The sending domain must be verified. Pass `scheduled_at` to send later. Set an `Idempotency-Key` header to make a retried request return the original email instead of sending twice.",
        "tags": [
          "Emails"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Client-chosen key, up to 255 characters. A repeat with the same key returns the original result.",
            "schema": {
              "type": "string",
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendEmailRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Queued.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendEmailResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Refused before queueing: unverified sending domain (`DOMAIN_NOT_VERIFIED`), every recipient suppressed (`ALL_SUPPRESSED`), no deliverable recipient domain (`RECIPIENT_DOMAIN_UNDELIVERABLE`), sending suspended or on hold (`SENDING_SUSPENDED`, `ACCOUNT_RESTRICTED`, `SERVICE_PAUSED`), a display name claiming a brand the domain has no relationship to (`SENDER_NOT_PERMITTED`), or a list-shaped send held for review (`LIST_SEND_HELD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited, or a sending ceiling reached (`RATE_LIMITED`, `DAILY_LIMIT_EXCEEDED`, `MONTHLY_LIMIT_EXCEEDED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listEmails",
        "summary": "List emails",
        "description": "Newest first, cursor-paginated. Filters combine with AND. Use `next_cursor` from the response as the next `cursor`.",
        "tags": [
          "Emails"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "description": "Items per page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 10
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "The `next_cursor` from the previous page.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "queued",
                "scheduled",
                "canceled",
                "sending",
                "sent",
                "delivered",
                "bounced",
                "complained",
                "suppressed",
                "failed"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Exact sender address match.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Case-insensitive match against any recipient.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "in": "query",
            "description": "Repeatable. `category:password_reset` matches that exact pair; a bare `category` matches any email carrying the tag. Several are ANDed.",
            "explode": true,
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of emails.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListEmailsResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/batch": {
      "post": {
        "operationId": "sendEmailBatch",
        "summary": "Send up to 100 emails",
        "description": "The body is a top-level array of email objects. Each item is accepted or refused independently — a failed item never fails the batch, and the response maps positionally to the request. Attachments and `scheduled_at` are not supported here; send those individually.",
        "tags": [
          "Emails"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "minItems": 1,
                "maxItems": 100,
                "items": {
                  "$ref": "#/components/schemas/SendEmailRequest"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-item outcomes.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchSendResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/{id}": {
      "get": {
        "operationId": "getEmail",
        "summary": "Get an email",
        "description": "The message with its full delivery event history, oldest event first.",
        "tags": [
          "Emails"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The email id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The email.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Email"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "rescheduleEmail",
        "summary": "Reschedule a scheduled email",
        "description": "Only an email still in `scheduled` status can be moved. Once sending has started this returns 409.",
        "tags": [
          "Emails"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The email id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateEmailRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rescheduled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateEmailResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The email is no longer reschedulable (`CONFLICT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/{id}/cancel": {
      "post": {
        "operationId": "cancelEmail",
        "summary": "Cancel a scheduled email",
        "description": "Only an email still in `scheduled` status can be cancelled. Once sending has started this returns 409.",
        "tags": [
          "Emails"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The email id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelEmailResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The email is no longer cancellable (`CONFLICT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/domains": {
      "post": {
        "operationId": "createDomain",
        "summary": "Register a sending domain",
        "description": "Generates a DKIM key pair and returns every DNS record to publish. DNS polling starts immediately; the domain cannot send until it reaches `verified`.",
        "tags": [
          "Domains"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDomainRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Registered. Publish `records`, then poll the domain.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateDomainResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "That domain is already verified on another account (`CONFLICT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listDomains",
        "summary": "List sending domains",
        "description": "Every domain on the organization with its verification status.",
        "tags": [
          "Domains"
        ],
        "responses": {
          "200": {
            "description": "The domains.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DomainListItem"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/domains/{id}": {
      "get": {
        "operationId": "getDomain",
        "summary": "Get a sending domain",
        "description": "Includes the DKIM public key, the DNS records to publish, and whether a verification chain is polling right now.",
        "tags": [
          "Domains"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The domain id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The domain.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteDomain",
        "summary": "Delete a sending domain",
        "description": "Removes the domain and rotates its DKIM key out of use. Keys scoped to it stop authenticating.",
        "tags": [
          "Domains"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The domain id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/domains/{id}/domain-connect": {
      "get": {
        "operationId": "getDomainConnect",
        "summary": "Check Domain Connect support for a domain",
        "description": "Asks whether the customer’s DNS provider can write the eusend records for them, and hands back the signed apply URL when it can. Evaluated per request — providers add and remove templates on their own schedule.",
        "tags": [
          "Domains"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The domain id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Supported, or the reason it is not.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainConnectResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/domains/{id}/verify": {
      "post": {
        "operationId": "verifyDomain",
        "summary": "Re-check the DNS records now",
        "description": "Starts a verification chain immediately instead of waiting for the next scheduled poll.",
        "tags": [
          "Domains"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The domain id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A check was started.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api-keys": {
      "post": {
        "operationId": "createApiKey",
        "summary": "Create an API key",
        "description": "The secret is returned once and never again. A test-mode key may only create further test-mode keys.",
        "tags": [
          "API keys"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created. Store `key` now.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateApiKeyResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listApiKeys",
        "summary": "List API keys",
        "description": "Metadata only — the secrets are hashed and cannot be read back.",
        "tags": [
          "API keys"
        ],
        "responses": {
          "200": {
            "description": "The keys.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ApiKey"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api-keys/{id}": {
      "delete": {
        "operationId": "revokeApiKey",
        "summary": "Revoke an API key",
        "description": "Takes effect immediately. Revoking a live key emails the organization owner.",
        "tags": [
          "API keys"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The API key id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/audiences": {
      "post": {
        "operationId": "createAudience",
        "summary": "Create an audience",
        "description": "An audience is a named contact list a broadcast can be sent to.",
        "tags": [
          "Audiences"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAudienceRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Audience"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listAudiences",
        "summary": "List audiences",
        "description": "Newest first, each with its current contact count.",
        "tags": [
          "Audiences"
        ],
        "responses": {
          "200": {
            "description": "The audiences.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListAudiencesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/audiences/{id}": {
      "delete": {
        "operationId": "deleteAudience",
        "summary": "Delete an audience",
        "description": "Deletes the audience and its contacts. Refused while a broadcast to it is scheduled or sending.",
        "tags": [
          "Audiences"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The audience id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "A scheduled or in-flight broadcast still needs this audience (`CONFLICT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/audiences/{id}/contacts": {
      "post": {
        "operationId": "createContact",
        "summary": "Add or upsert a contact",
        "description": "Addresses are lowercased. Adding an address already in the audience updates it rather than failing.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The audience id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created or updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listContacts",
        "summary": "List contacts in an audience",
        "description": "Newest first, cursor-paginated. Use `nextCursor` from the response as the next `cursor`.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The audience id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "search",
            "in": "query",
            "description": "Substring match on the email address.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "subscribed",
            "in": "query",
            "description": "true for subscribed only, false for unsubscribed only.",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of contacts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListContactsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/audiences/{id}/contacts/batch": {
      "post": {
        "operationId": "batchCreateContacts",
        "summary": "Upsert up to 1,000 contacts",
        "description": "For importing a list. Addresses are lowercased and de-duplicated server-side. An import can add an opt-out but never remove one.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The audience id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchContactsRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Imported.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchContactsResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The import would exceed the plan contact limit (`PLAN_LIMIT_EXCEEDED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/audiences/{id}/contacts/batch-delete": {
      "post": {
        "operationId": "batchDeleteContacts",
        "summary": "Delete up to 1,000 contacts by id",
        "description": "Removes contacts from the audience without suppressing them. To stop mailing someone while keeping the record, update the contact with `unsubscribed: true` instead.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The audience id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchDeleteContactsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedCountResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/audiences/{id}/contacts/{contactId}": {
      "get": {
        "operationId": "getContact",
        "summary": "Get a contact",
        "description": "One contact in an audience.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The audience id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "description": "The contact id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The contact.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateContact",
        "summary": "Update a contact",
        "description": "Change the name, or set `unsubscribed` to opt the contact in or out.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The audience id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "description": "The contact id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteContact",
        "summary": "Remove a contact",
        "description": "Removes the contact from the audience. This is not an unsubscribe.",
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The audience id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "description": "The contact id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Removed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/suppressions": {
      "get": {
        "operationId": "listSuppressions",
        "summary": "List suppressed addresses",
        "description": "The addresses this organization will not send to. Hard bounces and complaints are added automatically.",
        "tags": [
          "Suppressions"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "reason",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "bounce",
                "complaint",
                "manual"
              ]
            }
          },
          {
            "name": "email",
            "in": "query",
            "description": "Substring match. Pass a domain (`@acme.com`) to see every suppressed address there.",
            "schema": {
              "type": "string",
              "maxLength": 320
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of entries.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListSuppressionsResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createSuppression",
        "summary": "Suppress an address",
        "description": "Adding an address that is already suppressed returns the existing entry unchanged — a manual add never rewrites a real bounce or complaint. Refused for test-mode keys.",
        "tags": [
          "Suppressions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSuppressionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Already suppressed; the entry in force is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Suppression"
                }
              }
            }
          },
          "201": {
            "description": "Suppressed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Suppression"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The suppression list is full for this plan, or the key is test-mode (`PLAN_LIMIT_EXCEEDED`, `FORBIDDEN`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The address was modified concurrently; retry (`CONFLICT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/suppressions/batch": {
      "post": {
        "operationId": "importSuppressions",
        "summary": "Import up to 1,000 suppressed addresses",
        "description": "For carrying a suppression list over from another provider before the first send.",
        "tags": [
          "Suppressions"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImportSuppressionsRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Imported.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportSuppressionsResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The import would exceed the plan suppression cap, or the key is test-mode.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/suppressions/export": {
      "get": {
        "operationId": "exportSuppressions",
        "summary": "Download the suppression list as CSV",
        "description": "Streams the whole list as `email,reason,created_at`, sorted by address.",
        "tags": [
          "Suppressions"
        ],
        "responses": {
          "200": {
            "description": "The CSV file.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/suppressions/{id}": {
      "delete": {
        "operationId": "deleteSuppression",
        "summary": "Un-suppress an address",
        "description": "Accepts the entry id or the address itself (URL-encoded). Removing bounced or complained addresses in bulk is what damages sender reputation — do it when the address was fixed, not to retry a failing list.",
        "tags": [
          "Suppressions"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The entry id, or the suppressed email address.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Removed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedCountResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Test-mode keys cannot modify the suppression list (`FORBIDDEN`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/templates": {
      "post": {
        "operationId": "createTemplate",
        "summary": "Create a template",
        "description": "A stored HTML body with `{{variable}}` placeholders, referenced from a send by `template_id`.",
        "tags": [
          "Templates"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTemplateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listTemplates",
        "summary": "List templates",
        "description": "Newest first. Bodies are omitted; fetch one template to get its HTML.",
        "tags": [
          "Templates"
        ],
        "responses": {
          "200": {
            "description": "The templates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListTemplatesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}": {
      "get": {
        "operationId": "getTemplate",
        "summary": "Get a template",
        "description": "The template including its HTML body.",
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The template id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The template.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateTemplate",
        "summary": "Update a template",
        "description": "Only the fields present in the body are changed.",
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The template id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTemplateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteTemplate",
        "summary": "Delete a template",
        "description": "Emails already sent from it are unaffected.",
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The template id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}/preview": {
      "get": {
        "operationId": "previewTemplate",
        "summary": "Render a template preview",
        "description": "Returns the rendered HTML with the supplied variables substituted. Useful for checking a template before sending.",
        "tags": [
          "Templates"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The template id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "variables",
            "in": "query",
            "description": "A JSON object of substitution values, URL-encoded.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The rendered HTML.",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The template has no HTML body, or rendering failed (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts": {
      "post": {
        "operationId": "createBroadcast",
        "summary": "Create a broadcast",
        "description": "Creates it as a draft. Nothing is sent until the send endpoint is called.",
        "tags": [
          "Broadcasts"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBroadcastRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created as a draft.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Broadcast"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listBroadcasts",
        "summary": "List broadcasts",
        "description": "Newest first, with recipient and sent counts.",
        "tags": [
          "Broadcasts"
        ],
        "responses": {
          "200": {
            "description": "The broadcasts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListBroadcastsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts/{id}": {
      "get": {
        "operationId": "getBroadcast",
        "summary": "Get a broadcast",
        "description": "The broadcast with per-status recipient counts in `stats`.",
        "tags": [
          "Broadcasts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The broadcast id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The broadcast.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BroadcastDetail"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateBroadcast",
        "summary": "Update or schedule a broadcast",
        "description": "Editable while draft, scheduled or paused. Setting `scheduled_at` schedules it; setting it to null unschedules it back to draft.",
        "tags": [
          "Broadcasts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The broadcast id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBroadcastRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Broadcast"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The broadcast is in a state that cannot be edited, or was changed concurrently (`CONFLICT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteBroadcast",
        "summary": "Delete a broadcast",
        "description": "Only a draft or cancelled broadcast can be deleted.",
        "tags": [
          "Broadcasts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The broadcast id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Only draft or cancelled broadcasts can be deleted (`CONFLICT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts/{id}/send": {
      "post": {
        "operationId": "sendBroadcast",
        "summary": "Send, schedule, or resume a broadcast",
        "description": "Fans the broadcast out to its audience. Omit `scheduled_at` to start now. Requires a paid plan and a live API key; use the test endpoint on the free plan.",
        "tags": [
          "Broadcasts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The broadcast id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendBroadcastRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sending or scheduled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendBroadcastResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Refused: broadcasts need a paid plan (`PLAN_LIMIT_EXCEEDED`), the sending domain is unverified (`DOMAIN_NOT_VERIFIED`), the account is suspended or on hold (`SENDING_SUSPENDED`, `ACCOUNT_RESTRICTED`, `SERVICE_PAUSED`), or the broadcast is held for review (`BROADCAST_HELD`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The broadcast is not in a sendable state (`CONFLICT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts/{id}/test": {
      "post": {
        "operationId": "testBroadcast",
        "summary": "Send a test copy of a broadcast",
        "description": "Delivers the real message to up to 5 addresses on your own verified domains. Works on every plan including Free, costs send quota, and does not change the broadcast status. Requires a live API key — the mail really is delivered.",
        "tags": [
          "Broadcasts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The broadcast id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestBroadcastRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Test sent.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TestBroadcastResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "A recipient is neither an account email on this organization nor on a verified domain, or a test-mode key was used (`DOMAIN_NOT_VERIFIED`, `FORBIDDEN`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts/{id}/cancel": {
      "post": {
        "operationId": "cancelBroadcast",
        "summary": "Cancel a broadcast",
        "description": "Stops a scheduled or in-flight broadcast. Messages already handed to the MTA still deliver.",
        "tags": [
          "Broadcasts"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The broadcast id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Broadcast"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "The broadcast is not in a cancellable state (`CONFLICT`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks": {
      "post": {
        "operationId": "createWebhook",
        "summary": "Create a webhook",
        "description": "Returns the signing secret once at creation. Deliveries carry an HMAC signature header; verify it before trusting a payload.",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateWebhookResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The plan webhook limit is reached (`PLAN_LIMIT_EXCEEDED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listWebhooks",
        "summary": "List webhooks",
        "description": "Every webhook on the organization. Secrets are not included.",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "200": {
            "description": "The webhooks.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListWebhooksResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}": {
      "get": {
        "operationId": "getWebhook",
        "summary": "Get a webhook with recent deliveries",
        "description": "Includes the most recent delivery attempts, for debugging an endpoint that is not receiving events.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookWithDeliveries"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateWebhook",
        "summary": "Update a webhook",
        "description": "Change the destination URL or the subscribed events. The signing secret is unaffected.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "description": "The request body or query failed validation (`VALIDATION_ERROR`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhook",
        "summary": "Delete a webhook",
        "description": "Stops deliveries immediately.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmptyResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/secret": {
      "get": {
        "operationId": "getWebhookSecret",
        "summary": "Reveal the signing secret",
        "description": "Returns the secret used to sign deliveries for this webhook.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSecretResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/rotate-secret": {
      "post": {
        "operationId": "rotateWebhookSecret",
        "summary": "Rotate the signing secret",
        "description": "Issues a new secret and returns it. Deliveries signed with the old secret stop verifying immediately.",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The webhook id.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The new secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSecretResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, or revoked API key (`UNAUTHORIZED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "The key exists but may not reach this resource — a `sending_access` key outside the send paths, a test-mode key writing live state, or an account on hold (`FORBIDDEN`, `ACCOUNT_RESTRICTED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such resource on this organization (`NOT_FOUND`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (`RATE_LIMITED`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error (`INTERNAL_ERROR`). Carries `request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Liveness check",
        "description": "Answers whether the API process is serving. Touches no dependency. No authentication.",
        "tags": [
          "System"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Serving.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/health/ready": {
      "get": {
        "operationId": "getReadiness",
        "summary": "Readiness check",
        "description": "Also proves Postgres and Valkey are reachable. Returns 503 when a dependency is down, so a plain status-code monitor is enough. No authentication.",
        "tags": [
          "System"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Every dependency reachable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadyResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited (`RATE_LIMITED`). 60 requests per minute per IP.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "A dependency is unreachable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReadyResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An eusend API key, sent as `Authorization: Bearer eu_live_…`. Create one in the dashboard under API keys."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Every non-2xx response from the API has this shape. `code` is stable and safe to branch on; `error` is a human sentence that may change.",
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable explanation of the failure."
          },
          "code": {
            "type": "string",
            "enum": [
              "UNAUTHORIZED",
              "FORBIDDEN",
              "NOT_FOUND",
              "VALIDATION_ERROR",
              "RATE_LIMITED",
              "MONTHLY_LIMIT_EXCEEDED",
              "DAILY_LIMIT_EXCEEDED",
              "PLAN_LIMIT_EXCEEDED",
              "ALL_SUPPRESSED",
              "RECIPIENT_DOMAIN_UNDELIVERABLE",
              "DOMAIN_NOT_VERIFIED",
              "SENDING_SUSPENDED",
              "ACCOUNT_RESTRICTED",
              "SENDER_NOT_PERMITTED",
              "SERVICE_PAUSED",
              "LIST_SEND_HELD",
              "BROADCAST_HELD",
              "ATTACHMENT_STORAGE_ERROR",
              "INTERNAL_ERROR",
              "CONFLICT",
              "BAD_REQUEST",
              "PAYLOAD_TOO_LARGE"
            ],
            "description": "Stable machine-readable error code."
          },
          "request_id": {
            "type": "string",
            "description": "Correlation id, returned on 500s and echoed in the `X-Request-Id` header on every response. Quote it in support requests."
          }
        }
      },
      "EmailAddresses": {
        "description": "A single address, or a list of them. Accepts `Name <user@example.com>` form.",
        "oneOf": [
          {
            "type": "string",
            "format": "email"
          },
          {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            }
          }
        ]
      },
      "Tags": {
        "description": "Labels for log filtering and webhook routing. Accepts a flat object or Resend’s `[{ name, value }]` array; responses always use the object form. Up to 10 tags; names and values are ASCII letters, digits, underscores and dashes.",
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          {
            "type": "array",
            "maxItems": 10,
            "items": {
              "type": "object",
              "required": [
                "name",
                "value"
              ],
              "properties": {
                "name": {
                  "type": "string"
                },
                "value": {
                  "type": "string"
                }
              }
            }
          }
        ]
      },
      "Attachment": {
        "type": "object",
        "description": "One file on a message. Supply exactly one of `content` (inline base64) or `path` (a URL fetched at send time). Up to 20 attachments, 10 MB combined.",
        "required": [
          "filename"
        ],
        "properties": {
          "filename": {
            "type": "string",
            "maxLength": 256,
            "description": "Name the recipient sees."
          },
          "content": {
            "type": "string",
            "format": "byte",
            "description": "Base64-encoded file bytes."
          },
          "path": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "Public URL the server fetches at send time."
          },
          "content_type": {
            "type": "string",
            "maxLength": 255,
            "description": "MIME type; inferred from the filename when omitted."
          },
          "content_id": {
            "type": "string",
            "maxLength": 128,
            "description": "Content-ID for an inline attachment, referenced from HTML as `cid:<content_id>`."
          }
        }
      },
      "SendEmailRequest": {
        "type": "object",
        "description": "A single message. At least one of `html`, `text` or `template_id` is required. Unknown properties are rejected.",
        "required": [
          "from",
          "to"
        ],
        "additionalProperties": false,
        "properties": {
          "from": {
            "type": "string",
            "description": "Sender address, bare (`hello@acme.com`) or with a display name (`Acme <hello@acme.com>`). The domain must be verified on your account."
          },
          "to": {
            "$ref": "#/components/schemas/EmailAddresses"
          },
          "cc": {
            "$ref": "#/components/schemas/EmailAddresses"
          },
          "bcc": {
            "$ref": "#/components/schemas/EmailAddresses"
          },
          "reply_to": {
            "$ref": "#/components/schemas/EmailAddresses"
          },
          "subject": {
            "type": "string",
            "minLength": 1,
            "description": "Line breaks are rejected."
          },
          "html": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "description": "Render a stored template instead of inline `html`/`text`."
          },
          "variables": {
            "type": "object",
            "additionalProperties": true,
            "description": "Values substituted into the template or into `{{placeholders}}` in the body."
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Extra MIME headers. Line breaks in names or values are rejected."
          },
          "tags": {
            "$ref": "#/components/schemas/Tags"
          },
          "track_opens": {
            "type": "boolean",
            "description": "Overrides the organization default."
          },
          "track_clicks": {
            "type": "boolean",
            "description": "Overrides the organization default."
          },
          "attachments": {
            "type": "array",
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/Attachment"
            }
          },
          "scheduled_at": {
            "type": "string",
            "maxLength": 100,
            "description": "Send in the future, at most 30 days out. An ISO 8601 timestamp or natural language (`in 1 hour`, `tomorrow at 9am`). Relative phrasings resolve against the server clock in UTC."
          }
        }
      },
      "SendEmailResponse": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "The queued email id."
          }
        }
      },
      "BatchItemResult": {
        "description": "Per-item outcome, positionally mapped to the request array. Branch on the presence of `id`: a failed item never fails the whole batch.",
        "oneOf": [
          {
            "type": "object",
            "required": [
              "id"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "error",
              "code"
            ],
            "properties": {
              "error": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "enum": [
                  "UNAUTHORIZED",
                  "FORBIDDEN",
                  "NOT_FOUND",
                  "VALIDATION_ERROR",
                  "RATE_LIMITED",
                  "MONTHLY_LIMIT_EXCEEDED",
                  "DAILY_LIMIT_EXCEEDED",
                  "PLAN_LIMIT_EXCEEDED",
                  "ALL_SUPPRESSED",
                  "RECIPIENT_DOMAIN_UNDELIVERABLE",
                  "DOMAIN_NOT_VERIFIED",
                  "SENDING_SUSPENDED",
                  "ACCOUNT_RESTRICTED",
                  "SENDER_NOT_PERMITTED",
                  "SERVICE_PAUSED",
                  "LIST_SEND_HELD",
                  "BROADCAST_HELD",
                  "ATTACHMENT_STORAGE_ERROR",
                  "INTERNAL_ERROR",
                  "CONFLICT",
                  "BAD_REQUEST",
                  "PAYLOAD_TOO_LARGE"
                ]
              }
            }
          }
        ]
      },
      "BatchSendResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchItemResult"
            }
          }
        }
      },
      "EmailEvent": {
        "type": "object",
        "required": [
          "id",
          "type",
          "metadata",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "enum": [
              "sent",
              "delivered",
              "opened",
              "clicked",
              "bounced",
              "complained"
            ]
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Email": {
        "type": "object",
        "description": "A single message with its full delivery event history.",
        "required": [
          "id",
          "from",
          "to",
          "subject",
          "status",
          "tags",
          "testMode",
          "createdAt",
          "events"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "from": {
            "type": "string"
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bcc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "replyTo": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "type": "string"
          },
          "html": {
            "type": [
              "string",
              "null"
            ]
          },
          "text": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "scheduled",
              "canceled",
              "sending",
              "sent",
              "delivered",
              "bounced",
              "complained",
              "suppressed",
              "failed"
            ]
          },
          "tags": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "testMode": {
            "type": "boolean",
            "description": "True when sent with an `eu_test_` key; no mail left the system."
          },
          "templateId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "scheduledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailEvent"
            }
          }
        }
      },
      "EmailListItem": {
        "type": "object",
        "required": [
          "id",
          "from",
          "to",
          "subject",
          "status",
          "tags",
          "testMode",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "from": {
            "type": "string"
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "scheduled",
              "canceled",
              "sending",
              "sent",
              "delivered",
              "bounced",
              "complained",
              "suppressed",
              "failed"
            ]
          },
          "tags": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "testMode": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ListEmailsResponse": {
        "type": "object",
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailListItem"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "Pass as `cursor` to fetch the next page. Null on the last page."
          }
        }
      },
      "UpdateEmailRequest": {
        "type": "object",
        "required": [
          "scheduled_at"
        ],
        "additionalProperties": false,
        "properties": {
          "scheduled_at": {
            "type": "string",
            "maxLength": 100,
            "description": "The new send time. Same parsing as `scheduled_at` on send."
          }
        }
      },
      "UpdateEmailResponse": {
        "type": "object",
        "required": [
          "id",
          "status",
          "scheduled_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "scheduled"
            ]
          },
          "scheduled_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CancelEmailResponse": {
        "type": "object",
        "required": [
          "id",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "canceled"
            ]
          }
        }
      },
      "DnsRecord": {
        "type": "object",
        "description": "One record to publish on the sending domain.",
        "required": [
          "id",
          "type",
          "name",
          "value",
          "purpose",
          "description"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable key: `dkim`, `dmarc`, `returnPathSpf`, `returnPathMx`."
          },
          "type": {
            "type": "string",
            "enum": [
              "TXT",
              "MX"
            ]
          },
          "name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "priority": {
            "type": "integer",
            "description": "MX records only."
          },
          "purpose": {
            "type": "string",
            "enum": [
              "authentication",
              "policy",
              "alignment"
            ],
            "description": "`authentication` blocks sending when missing; `policy` is recommended; `alignment` is optional and enables Return-Path SPF alignment when both alignment records are published."
          },
          "description": {
            "type": "string"
          }
        }
      },
      "CreateDomainRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "description": "The domain itself (`acme.com`), not an address on it. Mailbox providers such as gmail.com are refused."
          }
        }
      },
      "CreateDomainResponse": {
        "type": "object",
        "required": [
          "id",
          "name",
          "records"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DnsRecord"
            },
            "description": "The full ordered record set. Prefer this over `dkim`/`dmarc`."
          },
          "dkim": {
            "$ref": "#/components/schemas/DnsRecord",
            "description": "Deprecated shortcut kept for SDK compatibility."
          },
          "dmarc": {
            "$ref": "#/components/schemas/DnsRecord",
            "description": "Deprecated shortcut kept for SDK compatibility."
          }
        }
      },
      "DomainListItem": {
        "type": "object",
        "required": [
          "id",
          "name",
          "status",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "verified",
              "failed"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Domain": {
        "type": "object",
        "required": [
          "id",
          "name",
          "status",
          "createdAt",
          "verification",
          "records"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "dkimPublicKey": {
            "type": "string"
          },
          "dkimSelector": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "verified",
              "failed"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "verifiedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "returnPathAligned": {
            "type": "boolean"
          },
          "verification": {
            "type": "object",
            "description": "Whether a DNS polling chain is running for this domain right now.",
            "required": [
              "running",
              "startedAt"
            ],
            "properties": {
              "running": {
                "type": "boolean"
              },
              "startedAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            }
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DnsRecord"
            }
          }
        }
      },
      "DomainConnectResponse": {
        "type": "object",
        "description": "Whether the domain’s DNS provider can publish our records for the customer. Not having Domain Connect is the ordinary case, so every negative answer is a 200 with `supported: false` — the caller’s job either way is to render the copy-paste records.",
        "required": [
          "supported"
        ],
        "properties": {
          "supported": {
            "type": "boolean"
          },
          "provider": {
            "type": "string",
            "description": "The DNS provider’s name, when one was identified."
          },
          "applyUrl": {
            "type": "string",
            "format": "uri",
            "description": "Signed URL to redirect the customer to. Present only when `supported` is true."
          },
          "reason": {
            "type": "string",
            "enum": [
              "not_configured",
              "no_domain_connect",
              "no_settings",
              "no_sync_flow",
              "template_not_onboarded",
              "lookup_failed"
            ],
            "description": "Why Domain Connect is unavailable. Present only when `supported` is false."
          }
        }
      },
      "MessageResponse": {
        "type": "object",
        "required": [
          "message"
        ],
        "properties": {
          "message": {
            "type": "string"
          }
        }
      },
      "EmptyResponse": {
        "type": "object",
        "description": "An empty object. The resource is gone.",
        "additionalProperties": false
      },
      "CreateApiKeyRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "test_mode": {
            "type": "boolean",
            "default": false,
            "description": "Mint an `eu_test_` key. A test key can only mint further test keys."
          },
          "permission": {
            "type": "string",
            "enum": [
              "full_access",
              "sending_access"
            ],
            "default": "full_access",
            "description": "`sending_access` reaches the send paths only; every other resource returns 403."
          },
          "domain_id": {
            "type": "string",
            "format": "uuid",
            "description": "Restrict the key to one sending domain. Valid only with `permission: sending_access`."
          }
        }
      },
      "CreateApiKeyResponse": {
        "type": "object",
        "required": [
          "id",
          "name",
          "key",
          "prefix",
          "test_mode",
          "permission",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "key": {
            "type": "string",
            "description": "The secret. Shown once, at creation, and never again."
          },
          "prefix": {
            "type": "string",
            "description": "First 12 characters, for identifying the key later."
          },
          "test_mode": {
            "type": "boolean"
          },
          "permission": {
            "type": "string",
            "enum": [
              "full_access",
              "sending_access"
            ]
          },
          "domain_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "domain_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "required": [
          "id",
          "name",
          "prefix",
          "testMode",
          "permission",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "testMode": {
            "type": "boolean"
          },
          "permission": {
            "type": "string",
            "enum": [
              "full_access",
              "sending_access"
            ]
          },
          "domainId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "domainName": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "CreateAudienceRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          }
        }
      },
      "Audience": {
        "type": "object",
        "required": [
          "id",
          "name",
          "organizationId",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "organizationId": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "AudienceListItem": {
        "type": "object",
        "required": [
          "id",
          "name",
          "createdAt",
          "contactCount"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "contactCount": {
            "type": "integer"
          }
        }
      },
      "ListAudiencesResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AudienceListItem"
            }
          }
        }
      },
      "Contact": {
        "type": "object",
        "required": [
          "id",
          "audienceId",
          "email",
          "status",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "audienceId": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "firstName": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastName": {
            "type": [
              "string",
              "null"
            ]
          },
          "properties": {
            "type": "object",
            "description": "Custom properties, usable as `{{key}}` in a broadcast body.",
            "additionalProperties": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "subscribed",
              "unsubscribed"
            ]
          },
          "unsubscribedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "CreateContactRequest": {
        "type": "object",
        "required": [
          "email"
        ],
        "additionalProperties": false,
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "first_name": {
            "type": "string",
            "maxLength": 100
          },
          "last_name": {
            "type": "string",
            "maxLength": 100
          },
          "properties": {
            "type": "object",
            "description": "Custom properties, available as `{{key}}` in a broadcast body. Keys are lowercase letters, digits and underscores, starting with a letter (max 40 characters, 20 properties per contact). `email`, `name`, `first_name`, `last_name` and `full_name` are built in and are rejected here.",
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            }
          }
        }
      },
      "UpdateContactRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "first_name": {
            "type": "string",
            "maxLength": 100
          },
          "last_name": {
            "type": "string",
            "maxLength": 100
          },
          "unsubscribed": {
            "type": "boolean",
            "description": "Set true to opt the contact out, false to resubscribe."
          },
          "properties": {
            "type": "object",
            "description": "Replaces the contact's custom properties. Omit to leave them unchanged; send `{}` to clear them.",
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            }
          }
        }
      },
      "ListContactsResponse": {
        "type": "object",
        "required": [
          "data",
          "nextCursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Contact"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        }
      },
      "BatchContactsRequest": {
        "type": "object",
        "required": [
          "contacts"
        ],
        "additionalProperties": false,
        "properties": {
          "contacts": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "type": "object",
              "required": [
                "email"
              ],
              "additionalProperties": false,
              "properties": {
                "email": {
                  "type": "string",
                  "format": "email"
                },
                "first_name": {
                  "type": "string",
                  "maxLength": 100
                },
                "last_name": {
                  "type": "string",
                  "maxLength": 100
                },
                "unsubscribed": {
                  "type": "boolean",
                  "description": "Carries an opt-out over from another provider. An import can only ever add an opt-out — `false` will not resubscribe someone."
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Original signup time. Applied on insert only."
                },
                "properties": {
                  "type": "object",
                  "description": "Custom properties, usable as `{{key}}` in a broadcast body. Unlike the single-contact endpoint, an import MERGES these into whatever the contact already has, so a CSV carrying only `plan` will not drop a `company` an earlier import set.",
                  "additionalProperties": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        }
      },
      "BatchContactsResponse": {
        "type": "object",
        "required": [
          "count",
          "duplicates"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "description": "Rows written."
          },
          "duplicates": {
            "type": "integer",
            "description": "Repeated addresses collapsed before the write."
          }
        }
      },
      "BatchDeleteContactsRequest": {
        "type": "object",
        "required": [
          "contact_ids"
        ],
        "additionalProperties": false,
        "properties": {
          "contact_ids": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "DeletedCountResponse": {
        "type": "object",
        "required": [
          "deleted"
        ],
        "properties": {
          "deleted": {
            "type": "integer",
            "description": "May be lower than what was asked for — an id may already be gone. Retries settle at 0 rather than failing."
          }
        }
      },
      "Suppression": {
        "type": "object",
        "required": [
          "id",
          "email",
          "reason",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "reason": {
            "type": "string",
            "enum": [
              "bounce",
              "complaint",
              "manual"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ListSuppressionsResponse": {
        "type": "object",
        "required": [
          "data",
          "next_cursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Suppression"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        }
      },
      "CreateSuppressionRequest": {
        "type": "object",
        "required": [
          "email"
        ],
        "additionalProperties": false,
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 320
          },
          "reason": {
            "type": "string",
            "enum": [
              "bounce",
              "complaint",
              "manual"
            ],
            "default": "manual",
            "description": "An add never overwrites the reason an address is already suppressed for."
          }
        }
      },
      "ImportSuppressionsRequest": {
        "type": "object",
        "required": [
          "emails"
        ],
        "additionalProperties": false,
        "properties": {
          "emails": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "description": "Bare addresses, objects, or a mix — so a CSV column can be posted unreshaped.",
            "items": {
              "oneOf": [
                {
                  "type": "string",
                  "format": "email",
                  "maxLength": 320
                },
                {
                  "type": "object",
                  "required": [
                    "email"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "email": {
                      "type": "string",
                      "format": "email",
                      "maxLength": 320
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "bounce",
                        "complaint",
                        "manual"
                      ],
                      "default": "manual"
                    }
                  }
                }
              ]
            }
          }
        }
      },
      "ImportSuppressionsResponse": {
        "type": "object",
        "required": [
          "count",
          "already_suppressed",
          "duplicates"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "description": "Entries written."
          },
          "already_suppressed": {
            "type": "integer",
            "description": "Entries already on the list."
          },
          "duplicates": {
            "type": "integer",
            "description": "Repeated addresses in the payload."
          }
        }
      },
      "CreateTemplateRequest": {
        "type": "object",
        "required": [
          "name",
          "subject",
          "html"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "subject": {
            "type": "string",
            "minLength": 1
          },
          "html": {
            "type": "string",
            "minLength": 1,
            "description": "May contain `{{variable}}` placeholders."
          },
          "editor_json": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Dashboard editor document, stored alongside the HTML so the visual editor can reopen it."
          }
        }
      },
      "UpdateTemplateRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "subject": {
            "type": "string",
            "minLength": 1
          },
          "html": {
            "type": "string",
            "minLength": 1
          },
          "editor_json": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          }
        }
      },
      "Template": {
        "type": "object",
        "required": [
          "id",
          "name",
          "subject",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "html": {
            "type": [
              "string",
              "null"
            ]
          },
          "reactSource": {
            "type": [
              "string",
              "null"
            ],
            "description": "Legacy field; no longer written."
          },
          "editorJson": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "TemplateListItem": {
        "type": "object",
        "required": [
          "id",
          "name",
          "subject",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ListTemplatesResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateListItem"
            }
          }
        }
      },
      "CreateBroadcastRequest": {
        "type": "object",
        "required": [
          "name",
          "audience_id",
          "from",
          "subject"
        ],
        "additionalProperties": false,
        "description": "Either `html` or `template_id` is required.",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "audience_id": {
            "type": "string",
            "format": "uuid"
          },
          "from": {
            "type": "string",
            "description": "Must be on a verified sending domain."
          },
          "reply_to": {
            "type": "string"
          },
          "subject": {
            "type": "string",
            "minLength": 1
          },
          "html": {
            "type": "string"
          },
          "editor_json": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "template_id": {
            "type": "string",
            "format": "uuid"
          },
          "template_variables": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "track_opens": {
            "type": "boolean"
          },
          "track_clicks": {
            "type": "boolean"
          }
        }
      },
      "UpdateBroadcastRequest": {
        "type": "object",
        "additionalProperties": false,
        "description": "Only a draft, scheduled or paused broadcast can be updated. Setting `scheduled_at` to null unschedules it back to draft.",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "audience_id": {
            "type": "string",
            "format": "uuid"
          },
          "from": {
            "type": "string"
          },
          "reply_to": {
            "type": [
              "string",
              "null"
            ]
          },
          "subject": {
            "type": "string",
            "minLength": 1
          },
          "html": {
            "type": "string"
          },
          "editor_json": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "template_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "template_variables": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "string"
            }
          },
          "scheduled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "track_opens": {
            "type": "boolean"
          },
          "track_clicks": {
            "type": "boolean"
          }
        }
      },
      "Broadcast": {
        "type": "object",
        "required": [
          "id",
          "name",
          "status",
          "fromAddress",
          "subject",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "organizationId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "scheduled",
              "sending",
              "sent",
              "paused",
              "held",
              "cancelled"
            ],
            "description": "`held` is a send stopped for review; unlike `paused` it is not resumable by the customer."
          },
          "audienceId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "fromAddress": {
            "type": "string"
          },
          "replyTo": {
            "type": [
              "string",
              "null"
            ]
          },
          "subject": {
            "type": "string"
          },
          "html": {
            "type": [
              "string",
              "null"
            ]
          },
          "reactSource": {
            "type": [
              "string",
              "null"
            ]
          },
          "editorJson": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "templateId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "templateVariables": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "string"
            }
          },
          "heldReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "scheduledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "startedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "recipientCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "sentCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "trackOpens": {
            "type": "boolean"
          },
          "trackClicks": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "BroadcastDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Broadcast"
          },
          {
            "type": "object",
            "required": [
              "stats"
            ],
            "properties": {
              "stats": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer"
                },
                "description": "Recipient counts keyed by email status, e.g. `{ \"delivered\": 1204, \"bounced\": 3 }`."
              }
            }
          }
        ]
      },
      "BroadcastListItem": {
        "type": "object",
        "required": [
          "id",
          "name",
          "status",
          "fromAddress",
          "subject",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "scheduled",
              "sending",
              "sent",
              "paused",
              "held",
              "cancelled"
            ]
          },
          "audienceId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "audienceName": {
            "type": [
              "string",
              "null"
            ]
          },
          "fromAddress": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "recipientCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "sentCount": {
            "type": [
              "integer",
              "null"
            ]
          },
          "scheduledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "startedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ListBroadcastsResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BroadcastListItem"
            }
          }
        }
      },
      "SendBroadcastRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "scheduled_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601. Omit to start sending immediately."
          }
        }
      },
      "SendBroadcastResponse": {
        "type": "object",
        "required": [
          "id",
          "status",
          "scheduled_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "sending",
              "scheduled"
            ]
          },
          "scheduled_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "TestBroadcastRequest": {
        "type": "object",
        "required": [
          "to"
        ],
        "additionalProperties": false,
        "properties": {
          "to": {
            "type": "array",
            "minItems": 1,
            "maxItems": 5,
            "items": {
              "type": "string",
              "format": "email"
            },
            "description": "Each address must be on a domain verified on your account — a test send delivers real mail without the paid-plan gate, so it is restricted to inboxes you have proved you control."
          }
        }
      },
      "TestBroadcastResponse": {
        "type": "object",
        "required": [
          "id",
          "sent_to",
          "email_ids"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "sent_to": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Addresses actually mailed, lowercased and de-duplicated."
          },
          "email_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        }
      },
      "CreateWebhookRequest": {
        "type": "object",
        "required": [
          "url",
          "events"
        ],
        "additionalProperties": false,
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS endpoint. Private, loopback and link-local addresses are refused."
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "email.sent",
                "email.delivered",
                "email.bounced",
                "email.complained",
                "email.opened",
                "email.clicked",
                "*"
              ]
            },
            "description": "Use `*` to subscribe to every event."
          }
        }
      },
      "UpdateWebhookRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "email.sent",
                "email.delivered",
                "email.bounced",
                "email.complained",
                "email.opened",
                "email.clicked",
                "*"
              ]
            }
          }
        }
      },
      "Webhook": {
        "type": "object",
        "required": [
          "id",
          "url",
          "events",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "email.sent",
                "email.delivered",
                "email.bounced",
                "email.complained",
                "email.opened",
                "email.clicked",
                "*"
              ]
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateWebhookResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Webhook"
          },
          {
            "type": "object",
            "required": [
              "secret"
            ],
            "properties": {
              "secret": {
                "type": "string",
                "description": "Signing secret for the `X-Eusend-Signature` HMAC. Retrievable later from the secret endpoint."
              }
            }
          }
        ]
      },
      "WebhookDelivery": {
        "type": "object",
        "required": [
          "id",
          "webhookId",
          "eventType",
          "status",
          "attempts",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "webhookId": {
            "type": "string",
            "format": "uuid"
          },
          "emailId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "eventType": {
            "type": "string"
          },
          "payload": {
            "type": "object",
            "additionalProperties": true
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "success",
              "failed"
            ]
          },
          "responseStatus": {
            "type": [
              "integer",
              "null"
            ]
          },
          "attempts": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastAttemptAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "WebhookWithDeliveries": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Webhook"
          },
          {
            "type": "object",
            "required": [
              "deliveries"
            ],
            "properties": {
              "deliveries": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/WebhookDelivery"
                }
              }
            }
          }
        ]
      },
      "ListWebhooksResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Webhook"
            }
          }
        }
      },
      "WebhookSecretResponse": {
        "type": "object",
        "required": [
          "secret"
        ],
        "properties": {
          "secret": {
            "type": "string"
          }
        }
      },
      "HealthResponse": {
        "type": "object",
        "required": [
          "status",
          "timestamp"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok"
            ]
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ReadyResponse": {
        "type": "object",
        "required": [
          "status",
          "checks",
          "timestamp"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "degraded"
            ]
          },
          "checks": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "`ok` per dependency, or the failure message.",
            "properties": {
              "postgres": {
                "type": "string"
              },
              "valkey": {
                "type": "string"
              }
            }
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}