{
  "openapi": "3.1.0",
  "info": {
    "title": "ZapSMTP API",
    "version": "1",
    "description": "Send, receive and track email. Docs: https://www.zapsmtp.xyz/docs/",
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://zapsmtp.xyz/v1"
    }
  ],
  "security": [
    {
      "bearer": []
    }
  ],
  "tags": [
    {
      "name": "Emails",
      "description": "Send one email or up to 100 in a batch, schedule them, and follow every recipient from acceptance to the remote server’s reply. Sending to …@simulator.zapsmtp.xyz with a test key runs the whole pipeline without delivering anything."
    },
    {
      "name": "Domains",
      "description": "Add the domain you send from, publish the DNS records it returns (DKIM, SPF, DMARC) and verify it. Live keys can only send from verified domains."
    },
    {
      "name": "Webhooks",
      "description": "Register an HTTPS endpoint and choose events. Every request is signed; see Webhook events for payloads and signature verification. filter.actions narrows email.clicked to some click actions."
    },
    {
      "name": "Click actions",
      "description": "Mark a link with data-zap-action=\"confirm_order\" and its clicks arrive as email.clicked with click.action; a webhook can take only the actions you list in filter.actions. Declaring an action here is optional: it gives it a description. The catalogue also lists the actions links used without one. See the Click actions guide."
    },
    {
      "name": "Templates",
      "description": "Edit a draft, then publish it: sends always use the published version, so changes go live only when you say so. Templates use logic-less Mustache: {{name}} is escaped, {{{html}}} is raw, sections repeat over lists. Send with template: {id, variables} on Send an email; variable_schema declares each variable’s type, whether a send must give it and its default (see Variables). Every save is kept in the version history (the newest 50), ready to restore."
    },
    {
      "name": "Variables",
      "description": "One list of every variable your templates can use: ZapSMTP’s own ({{{zap:unsubscribe_url}}}), the account’s global ones ({{global.company_name}}, set here and never by a send) and each template’s own, with where each is used. See Variables in the templates guide."
    },
    {
      "name": "Modules, images & timers",
      "description": "What the visual editor shares across templates: modules (saved rows any template can insert), images hosted on a public URL, and countdown timer images. All of it works through the API too."
    },
    {
      "name": "Received emails",
      "description": "Messages sent to your inbound addresses land here. The email.received webhook carries metadata only; fetch bodies and attachments with these endpoints."
    },
    {
      "name": "Inbound setup",
      "description": "Get an instant managed address or receive on your own domain, then route messages by recipient, sender or header to a webhook, storage or rejection."
    },
    {
      "name": "Suppressions",
      "description": "Permanent mailbox or domain failures, complaints and one-click unsubscribes add an address here automatically. Sends to a suppressed address are skipped and reported as email.suppressed. An unsubscribe stops only broadcast email; transactional email to that address still goes out."
    },
    {
      "name": "Statistics",
      "description": "Counts for the window you ask for, limited to your plan’s log retention."
    },
    {
      "name": "API keys & SMTP credentials",
      "description": "Use separate keys per application and environment. Test keys (zap_test_…) run the full pipeline without delivering. SMTP credentials have their own username and password and never authorize the HTTP API."
    },
    {
      "name": "Logs & usage",
      "description": "Find out exactly what your code sent and what we answered. Every response’s X-Request-Id is the id of its log entry."
    },
    {
      "name": "Simulator & dedicated IPs",
      "description": "List the simulator scenarios and your dedicated IPs with their warm-up and blocklist status."
    }
  ],
  "paths": {
    "/emails": {
      "post": {
        "operationId": "send-email",
        "summary": "Send an email",
        "description": "Send an email (or schedule it with scheduled_at). Requires a full-access or sending-access key. Live keys: From domain must be verified by the account. Test keys: any From domain, nothing delivered, monthly quota not charged. Recipients are deduplicated and lowercased; max 50 across to+cc+bcc. Message-ID is <id>@<hostname>, or <id>.<thread_id>@<hostname> for a reply that continues a conversation. The response also carries thread_id: the conversation this email belongs to. An email with In-Reply-To / References headers (set them in headers) joins the thread of the message it answers; otherwise it starts a new one. failed_recipients: addresses the mail server refused while it took the others; they are not sent and not charged. unconfirmed: true: the mail server took the message but its answer was lost; it counts as sent and must not be retried (its events tell the outcome). Scheduled emails (scheduled_at): at most 10,000 (256 MB) may wait per account. At send time the account and the key are checked again: a suspended account or a revoked or expired key fails the email. With reply tracking on, the response carries reply_to: the tracked address the email carries in place of its own Reply-To. Human replies are forwarded to the domain’s reply_forward_to, else to the email’s first Reply-To, else to its From.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.send",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "optional, 1-256 bytes (see Idempotency)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendEmailResponse"
                },
                "example": {
                  "id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23"
                }
              }
            }
          },
          "400": {
            "description": "validation_error: invalid JSON / unknown field\ninvalid_idempotency_key: Idempotency-Key must be 1 to 256 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "domain_not_verified: sender domain is not verified for this account\nrestricted_api_key: key restricted to another domain or stream\naccount_suspended: account is suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_reused: \nidempotency_request_in_progress: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: request body exceeds 40MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "421": {
            "description": "misdirected_cell: the account is served by another cell: \"this account is served by cell <cell> at <url>\", Zap-Cell: <cell>; send to that URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "missing_required_field: \ninvalid_parameter: e.g. too many recipients (max 50), invalid address, bad tags/metadata/stream/scheduled_at, \"at least one recipient is required\"\ninvalid_attachment: \ntemplate_render_error: \ntemplate_variables_invalid: template variables of the wrong type: a, b (checked against the published variable schema)\ntemplate_variables_missing: missing required template variables: a, b (required, no value and no default)\nrejected: the mail transfer agent refused the message: <reason>",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limit_exceeded: rate limit exceeded\nmonthly_quota_exceeded: monthly quota exceeded\ndaily_quota_exceeded: daily sending limit reached; it resets at 00:00 UTC\noverloaded: server at capacity (\"the server is at capacity; retry shortly\", Retry-After: 1) or event pipeline backed up (\"the event pipeline is backed up; retry shortly\", Retry-After: 5); nothing sent, retry",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "service_unavailable: a backing store failing over (\"a backing service is failing over; retry shortly\", Retry-After: 2); MTA unreachable (\"mail transfer agent temporarily unavailable, retry\"), suppression list being rebuilt (\"suppression list is being rebuilt, retry shortly\"), or too many large request bodies in flight (Retry-After: 5)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendEmailParams"
              },
              "example": {
                "from": "Acme <hello@acme.com>",
                "to": [
                  "delivered@simulator.zapsmtp.xyz"
                ],
                "subject": "Your receipt",
                "html": "<p>Thanks for your order.</p>",
                "tags": [
                  {
                    "name": "category",
                    "value": "receipt"
                  }
                ],
                "metadata": {
                  "order_id": "A-1042"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "list-emails",
        "summary": "List emails",
        "description": "List sent emails, newest first. Requires a full-access key. Use the last item's id as before= for the next page. metadata may be null when the email has none. last_status and last_event carry the same value.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.list",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-100; out-of-range values fall back to 20.",
            "schema": {
              "type": "integer",
              "default": "20"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Cursor: an email id (UUIDv7) or RFC 3339 time; returns emails accepted before it. An email id gives an exact page boundary. Limits: 422 invalid_parameter \"before must be an email id or RFC 3339 time\"",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Email id or RFC 3339 time; only emails created after it (still newest first). Limits: 422 invalid_parameter \"after must be an email id or RFC 3339 time\"",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by latest status. status=scheduled lists pending scheduled sends instead (different item shape, ordered by scheduled time ascending, has_more always false, other filters/cursors ignored).",
            "schema": {
              "type": "string",
              "enum": [
                "queued",
                "delivered",
                "delivery_delayed",
                "bounced",
                "complained",
                "failed",
                "opened",
                "clicked",
                "replied",
                "suppressed",
                "scheduled"
              ]
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Case-insensitive substring of a recipient or subject, or an exact email id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Look-back window in days, 1-90 (other values ignored). Always capped by the plan's log retention.",
            "schema": {
              "type": "integer",
              "default": "30"
            }
          },
          {
            "name": "stream",
            "in": "query",
            "required": false,
            "description": "",
            "schema": {
              "type": "string",
              "enum": [
                "transactional",
                "broadcast"
              ]
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "description": "Filter live or test-mode (sandbox) traffic; other values ignored.",
            "schema": {
              "type": "string",
              "enum": [
                "live",
                "test"
              ]
            }
          },
          {
            "name": "metadata",
            "in": "query",
            "style": "deepObject",
            "explode": true,
            "required": false,
            "description": "Exact match on a metadata value, e.g. metadata[order_id]=A-1042. Repeatable for several keys.",
            "schema": {
              "type": "object",
              "additionalProperties": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Email"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": true,
                  "data": [
                    {
                      "object": "email",
                      "id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23",
                      "from": "Acme <hello@acme.com>",
                      "subject": "Your receipt",
                      "to": [
                        "jane@example.org"
                      ],
                      "last_status": "delivered",
                      "last_event": "delivered",
                      "created_at": "2026-10-21T15:04:10.902Z",
                      "stream": "transactional",
                      "test": false,
                      "metadata": {
                        "order_id": "A-1042"
                      }
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: bad before/after",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/batch": {
      "post": {
        "operationId": "send-batch",
        "summary": "Send a batch",
        "description": "Send 1-100 emails in one request. Requires a full-access or sending-access key. Test keys follow the same rules as for sending. Per-email error codes use the same classification as POST /emails (domain_not_verified, restricted_api_key, rate_limit_exceeded, monthly_quota_exceeded, etc. appear inside errors[] rather than as the HTTP status). Emails are sent concurrently (up to 16 at a time); each email may have its own scheduled_at. Body: length 1-100 else 422 invalid_parameter \"batch must contain 1 to 100 emails\" An item of data carries reply_to when reply tracking is on for that email.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.sendBatch",
        "parameters": [
          {
            "name": "x-batch-validation",
            "in": "header",
            "required": false,
            "description": "strict (default) | permissive (case-insensitive). strict: if any email fails validation nothing is sent and 422 is returned. permissive: valid emails are sent; invalid ones are reported in errors.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "optional, 1-256 bytes",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendBatchResponse"
                },
                "example": {
                  "data": [
                    {
                      "index": 0,
                      "id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23"
                    },
                    {
                      "index": 2,
                      "id": "019a1f2e-7c3c-7a10-8b21-4d5e6f7a8b9c",
                      "suppressed": [
                        "old@example.org"
                      ]
                    }
                  ],
                  "errors": [
                    {
                      "index": 1,
                      "code": "missing_required_field",
                      "message": "subject is required"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "validation_error: invalid JSON or x-batch-validation not strict/permissive\ninvalid_idempotency_key: Idempotency-Key must be 1 to 256 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_reused: \nidempotency_request_in_progress: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: batch size outside 1-100\nvalidation_error: strict mode, any email invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "service_unavailable: too many large bodies in flight",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "minItems": 1,
                "maxItems": 100,
                "items": {
                  "$ref": "#/components/schemas/SendEmailParams"
                }
              },
              "example": [
                {
                  "from": "Acme <hello@acme.com>",
                  "to": [
                    "delivered@simulator.zapsmtp.xyz"
                  ],
                  "subject": "Hello Ann",
                  "text": "Hi Ann!"
                },
                {
                  "from": "Acme <hello@acme.com>",
                  "to": [
                    "bounced@simulator.zapsmtp.xyz"
                  ],
                  "subject": "Hello Bob",
                  "text": "Hi Bob!"
                }
              ]
            }
          }
        }
      }
    },
    "/emails/{id}": {
      "get": {
        "operationId": "get-email",
        "summary": "Retrieve an email",
        "description": "Retrieve one email with per-recipient status and its event timeline. Requires a full-access key. Only data inside the plan's log retention is visible. metadata may be null.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Email id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Email"
                },
                "example": {
                  "object": "email",
                  "id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23",
                  "from": "Acme <hello@acme.com>",
                  "subject": "Your receipt",
                  "created_at": "2026-10-21T15:04:10.902Z",
                  "recipients": [
                    {
                      "email": "jane@example.org",
                      "status": "delivered",
                      "updated_at": "2026-10-21T15:04:12.381Z",
                      "response": "250 2.0.0 OK 1761059052 x7si123"
                    }
                  ],
                  "events": [
                    {
                      "type": "Reception",
                      "status": "queued",
                      "recipient": "jane@example.org",
                      "time": "2026-10-21T15:04:10.902Z",
                      "attempts": 0
                    },
                    {
                      "type": "Delivery",
                      "status": "delivered",
                      "recipient": "jane@example.org",
                      "time": "2026-10-21T15:04:12.381Z",
                      "response_code": 250,
                      "response": "250 2.0.0 OK 1761059052 x7si123",
                      "attempts": 1,
                      "mx": "gmail-smtp-in.l.google.com.",
                      "peer_addr": "142.250.153.27",
                      "tls": "TLSv1.3 TLS_AES_256_GCM_SHA384",
                      "egress_source": "ip-1"
                    }
                  ],
                  "stream": "transactional",
                  "test": false,
                  "metadata": {
                    "order_id": "A-1042"
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: email not found (events can take a few seconds to appear)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "reschedule-email",
        "summary": "Reschedule an email",
        "description": "Reschedule a scheduled email. Requires a full-access or sending-access key. Unknown ids return 409 not_cancellable, not 404.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Scheduled email id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Email"
                },
                "example": {
                  "object": "email",
                  "id": "019a1f40-2b3c-7d4e-8f5a-6b7c8d9e0f12",
                  "status": "scheduled",
                  "last_event": "scheduled",
                  "scheduled_at": "2026-10-23T09:00:00Z",
                  "from": "Acme <hello@acme.com>",
                  "to": [
                    "jane@example.org"
                  ],
                  "subject": "Your weekly digest",
                  "created_at": "2026-10-21T16:20:05.114Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: this API key cannot manage this email (another domain or stream, or live mail with a test key)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "not_cancellable: only scheduled emails can be updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "missing_required_field: \ninvalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scheduled_at": {
                    "type": "string",
                    "description": "RFC 3339 or \"in <n> <unit>\" (see POST /emails). A time in the past dispatches as soon as possible. Limits: missing → 422 missing_required_field; unparsable or > 7 days ahead → 422 invalid_parameter"
                  }
                },
                "required": [
                  "scheduled_at"
                ]
              },
              "example": {
                "scheduled_at": "in 2 hours"
              }
            }
          }
        }
      }
    },
    "/emails/{id}/content": {
      "get": {
        "operationId": "get-email-content",
        "summary": "Retrieve email content",
        "description": "Retrieve the archived content of a sent email. Requires a full-access key. source is api or smtp; tags is the URL-encoded tag string. Content is kept for your plan’s log retention.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.getContent",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Email id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailContent"
                },
                "example": {
                  "source": "api",
                  "from": "Acme <hello@acme.com>",
                  "to": [
                    "jane@example.org"
                  ],
                  "cc": [],
                  "bcc": [],
                  "subject": "Your receipt",
                  "html": "<p>Thanks for your order!</p>",
                  "text": "Thanks for your order!",
                  "raw": "",
                  "tags": "category=receipt",
                  "size": 2481
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: content not available (past your plan's log retention)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/{id}/cancel": {
      "post": {
        "operationId": "cancel-email",
        "summary": "Cancel a scheduled email",
        "description": "Cancel a scheduled email before it is dispatched. Requires a full-access or sending-access key.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.cancel",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Scheduled email id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Email"
                },
                "example": {
                  "object": "email",
                  "id": "019a1f40-2b3c-7d4e-8f5a-6b7c8d9e0f12",
                  "status": "canceled"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: this API key cannot manage this email (another domain or stream, or live mail with a test key)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "not_cancellable: unknown id, already dispatched or already canceled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/spam-check": {
      "post": {
        "operationId": "spam-check-draft",
        "summary": "Spam-check a draft",
        "description": "Score a draft for spam before sending (nothing is sent or stored). Requires a full-access or sending-access key. Body: from missing or both html and text empty → 422 missing_required_field \"from and html or text are required\". Only these six fields are accepted (others → 400).",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.spamCheck",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpamCheck"
                },
                "example": {
                  "object": "spam_check",
                  "score": 1.3,
                  "threshold": 5,
                  "verdict": "good",
                  "engines": [
                    {
                      "engine": "spamassassin",
                      "score": 1.3,
                      "threshold": 5,
                      "verdict": "good",
                      "rules": [
                        {
                          "name": "HTML_MESSAGE",
                          "score": 0.001,
                          "description": "HTML included in message"
                        },
                        {
                          "name": "MIME_HTML_ONLY",
                          "score": 1.1,
                          "description": "Message only has text/html MIME parts"
                        }
                      ]
                    },
                    {
                      "engine": "rspamd",
                      "score": 0.8,
                      "threshold": 6,
                      "verdict": "good",
                      "rules": [
                        {
                          "name": "MIME_HTML_ONLY",
                          "score": 0.2,
                          "description": "Messages that have only HTML part"
                        }
                      ]
                    }
                  ],
                  "dkim_signed": true,
                  "sending_ip": "203.0.113.25",
                  "issues": [],
                  "note": "Scored as a receiving server sees it: DKIM-signed with your key, sent from your egress IP, checked against live DNS blocklists. SpamAssassin is the headline score (≥ 5 = spam); rspamd is shown alongside."
                }
              }
            }
          },
          "422": {
            "description": "missing_required_field: \ninvalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limit_exceeded: spam checks are limited to 30 per minute",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "service_unavailable: spam checks are busy, try again shortly\nscanner_unavailable: the spam scanners are temporarily unavailable, try again",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "from": {
                    "type": "string",
                    "description": "From address; when its domain is verified by the account the draft is DKIM-signed with the real key."
                  },
                  "to": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ],
                    "description": "Recipient(s); the first is used as envelope recipient. Limits: 422 invalid_parameter \"to must be a string or an array of strings\""
                  },
                  "subject": {
                    "type": "string"
                  },
                  "html": {
                    "type": "string",
                    "description": "At least one of html and text is required."
                  },
                  "text": {
                    "type": "string"
                  },
                  "stream": {
                    "type": "string",
                    "description": "Selects the shared pool used to pick the egress IP when the account has no dedicated IP."
                  }
                },
                "required": [
                  "from"
                ]
              },
              "example": {
                "from": "Acme <hello@acme.com>",
                "subject": "Your receipt",
                "html": "<p>Thanks for your order.</p>"
              }
            }
          }
        }
      }
    },
    "/emails/{id}/spam-check": {
      "post": {
        "operationId": "spam-check-email",
        "summary": "Spam-check a sent email",
        "description": "Score an already sent email (live or test) from the content archive. Requires a full-access key. Always scored with the transactional pool's IP when the account has no dedicated IP. Availability follows GET /emails/{id}/content (plan log retention), although the 404 message says 7 days.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.spamCheckSent",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Email id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SpamCheck"
                },
                "example": {
                  "object": "spam_check",
                  "score": 6.2,
                  "threshold": 5,
                  "verdict": "spam",
                  "engines": [
                    {
                      "engine": "spamassassin",
                      "score": 6.2,
                      "threshold": 5,
                      "verdict": "spam",
                      "rules": [
                        {
                          "name": "URIBL_BLOCKED",
                          "score": 0.001,
                          "description": "ADMINISTRATOR NOTICE: The query to URIBL was blocked"
                        }
                      ]
                    },
                    {
                      "engine": "rspamd",
                      "score": 4.1,
                      "threshold": 6,
                      "verdict": "needs_work",
                      "rules": []
                    }
                  ],
                  "dkim_signed": false,
                  "sending_ip": "203.0.113.25",
                  "issues": [
                    {
                      "kind": "not_signed",
                      "message": "The From domain is not verified, so the message is not DKIM-signed and fails DMARC. Verify the domain before sending."
                    }
                  ],
                  "note": "Scored as a receiving server sees it: DKIM-signed with your key, sent from your egress IP, checked against live DNS blocklists. SpamAssassin is the headline score (≥ 5 = spam); rspamd is shown alongside.",
                  "email_id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: content not available (kept for 7 days)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limit_exceeded: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "service_unavailable: \nscanner_unavailable: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/{id}/attachments": {
      "get": {
        "operationId": "list-sent-attachments",
        "summary": "List attachments",
        "description": "Attachments of a sent email, each with a download link valid for one hour. Requires a full-access key. Emails sent without attachments return an empty list.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.attachments.list",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Email id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Attachment"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "object": "attachment",
                      "id": "att_1",
                      "filename": "invoice.pdf",
                      "content_type": "application/pdf",
                      "content_disposition": "attachment",
                      "content_id": "",
                      "size": 20480,
                      "download_url": "https://zapsmtp.xyz/v1/files/eyJ0Ijoi…",
                      "expires_at": "2026-10-22T16:04:10Z"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown email, or past your plan’s log retention.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/{id}/attachments/{aid}": {
      "get": {
        "operationId": "get-sent-attachment",
        "summary": "Retrieve an attachment",
        "description": "One attachment of a sent email with a fresh download link. Requires a full-access key.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.attachments.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Email id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "aid",
            "in": "path",
            "required": true,
            "description": "Attachment id from the list.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Attachment"
                },
                "example": {
                  "object": "attachment",
                  "id": "att_1",
                  "filename": "invoice.pdf",
                  "content_type": "application/pdf",
                  "content_disposition": "attachment",
                  "content_id": "",
                  "size": 20480,
                  "download_url": "https://zapsmtp.xyz/v1/files/eyJ0Ijoi…",
                  "expires_at": "2026-10-22T16:04:10Z"
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown email or attachment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/{id}/share": {
      "post": {
        "operationId": "share-email",
        "summary": "Share an email",
        "description": "Create a link anyone can open to view a sent email — for a colleague or support. It shows the subject, sender, recipients and body; never attachments or headers. Requires a full-access live key; test keys get 403 test_key_restricted. The page renders the body in a sandbox: scripts, forms and external requests other than images are blocked.",
        "tags": [
          "Emails"
        ],
        "x-sdk-method": "emails.share",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Email id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailShare"
                },
                "example": {
                  "object": "email_share",
                  "email_id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23",
                  "url": "https://zapsmtp.xyz/t/s/eyJ0Ijoi…",
                  "expires_at": "2026-10-25T15:04:10Z"
                }
              }
            }
          },
          "403": {
            "description": "test_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown email, or past your plan’s log retention.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: expires_in_hours out of range.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "expires_in_hours": {
                    "type": "integer",
                    "description": "1–720."
                  }
                }
              },
              "example": {
                "expires_in_hours": 72
              }
            }
          }
        }
      }
    },
    "/domains": {
      "get": {
        "operationId": "list-domains",
        "summary": "List domains",
        "description": "List sending domains (newest first) with their DNS records. Requires a full-access key. status is pending or verified. Only DKIM is required to verify a domain; SPF and DMARC are recommended and reported separately.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Domain"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "019a1f10-8a10-7b22-8c31-5d2e9f0a4b17",
                      "name": "acme.com",
                      "status": "verified",
                      "dkim_selector": "zap",
                      "dkim_verified": true,
                      "spf_verified": true,
                      "dmarc_verified": true,
                      "open_tracking": false,
                      "click_tracking": false,
                      "from_name": "Acme",
                      "tls": "opportunistic",
                      "reply_tracking": false,
                      "reply_domain": "",
                      "reply_forward_to": "",
                      "brand_updated_at": null,
                      "last_checked_at": "2026-10-21T09:12:44Z",
                      "verified_at": "2026-10-20T14:03:10Z",
                      "created_at": "2026-10-20T13:58:02Z",
                      "zone": "acme.com",
                      "records": [
                        {
                          "record": "DKIM",
                          "type": "TXT",
                          "name": "zap._domainkey.acme.com",
                          "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...",
                          "required": true,
                          "status": "verified"
                        },
                        {
                          "record": "SPF",
                          "type": "TXT",
                          "name": "acme.com",
                          "value": "v=spf1 include:_spf.zapsmtp.xyz ~all",
                          "required": false,
                          "status": "verified"
                        },
                        {
                          "record": "DMARC",
                          "type": "TXT",
                          "name": "_dmarc.acme.com",
                          "value": "v=DMARC1; p=none;",
                          "required": false,
                          "status": "verified"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-domain",
        "summary": "Add a domain",
        "description": "Add a sending domain; returns the DNS records to publish. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                },
                "example": {
                  "id": "019a1f10-8a10-7b22-8c31-5d2e9f0a4b17",
                  "name": "acme.com",
                  "status": "pending",
                  "dkim_selector": "zap",
                  "dkim_verified": false,
                  "spf_verified": false,
                  "dmarc_verified": false,
                  "open_tracking": false,
                  "click_tracking": false,
                  "from_name": "",
                  "tls": "opportunistic",
                  "reply_tracking": false,
                  "reply_domain": "",
                  "reply_forward_to": "",
                  "brand_updated_at": null,
                  "last_checked_at": null,
                  "verified_at": null,
                  "created_at": "2026-10-21T13:58:02Z",
                  "zone": "acme.com",
                  "records": [
                    {
                      "record": "DKIM",
                      "type": "TXT",
                      "name": "zap._domainkey.acme.com",
                      "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...",
                      "required": true,
                      "status": "pending"
                    },
                    {
                      "record": "SPF",
                      "type": "TXT",
                      "name": "acme.com",
                      "value": "v=spf1 include:_spf.zapsmtp.xyz ~all",
                      "required": false,
                      "status": "pending"
                    },
                    {
                      "record": "DMARC",
                      "type": "TXT",
                      "name": "_dmarc.acme.com",
                      "value": "v=DMARC1; p=none;",
                      "required": false,
                      "status": "pending"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "plan_limit_reached: the <Plan> plan includes <n> domains; upgrade your plan to add more\nrestricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict: domain already added",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: invalid domain name",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Domain name (lowercased, trailing dot removed). Limits: valid hostname <=253 chars, else 422 invalid_parameter \"invalid domain name\""
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "mail.acme.com"
              }
            }
          }
        }
      }
    },
    "/domains/{id}": {
      "get": {
        "operationId": "get-domain",
        "summary": "Retrieve a domain",
        "description": "Retrieve a sending domain. Requires a full-access key.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "update-domain",
        "summary": "Update a domain",
        "description": "Set the domain's tracking defaults (opens, clicks, replies) and its outbound TLS policy. Requires a full-access live key; test keys get 403 test_key_restricted. Fields left out keep their value. The response is the domain, as in GET /domains/{id}. Reply tracking: each tracked email gets its own signed Reply-To, e.g. r1-<email id>.<signature>@reply.acme.com, so replies come back tied to the exact email. Each reply fires email.replied (classified as a person, out-of-office, unsubscribe request, bounce…) and arrives as a received email; only replies a person wrote are forwarded. The display name is kept (the Reply-To’s name, else the From name). One reply address takes at most 100 replies a day.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                },
                "example": {
                  "id": "019a1f10-8a10-7b22-8c31-5d2e9f0a4b17",
                  "name": "acme.com",
                  "status": "verified",
                  "dkim_selector": "zap",
                  "dkim_verified": true,
                  "spf_verified": true,
                  "dmarc_verified": true,
                  "open_tracking": true,
                  "click_tracking": true,
                  "from_name": "",
                  "tls": "opportunistic",
                  "reply_tracking": true,
                  "reply_domain": "reply.acme.com",
                  "reply_forward_to": "support@acme.com",
                  "brand_updated_at": null,
                  "last_checked_at": "2026-10-21T14:05:00Z",
                  "verified_at": "2026-10-21T14:05:00Z",
                  "created_at": "2026-10-21T13:58:02Z",
                  "zone": "acme.com",
                  "records": [
                    {
                      "record": "DKIM",
                      "type": "TXT",
                      "name": "zap._domainkey.acme.com",
                      "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...",
                      "required": true,
                      "status": "verified"
                    },
                    {
                      "record": "SPF",
                      "type": "TXT",
                      "name": "acme.com",
                      "value": "v=spf1 include:_spf.zapsmtp.xyz ~all",
                      "required": false,
                      "status": "verified"
                    },
                    {
                      "record": "DMARC",
                      "type": "TXT",
                      "name": "_dmarc.acme.com",
                      "value": "v=DMARC1; p=none;",
                      "required": false,
                      "status": "verified"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: bad tls; reply_domain not one of your inbound domains, not this domain or a subdomain of it, or without a verified MX record; reply_forward_to not a plain address, a receiving address, or not on a verified domain / confirmed forward destination; reply_tracking without a reply_domain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "open_tracking": {
                    "type": "boolean",
                    "description": "Default open tracking for emails from this domain."
                  },
                  "click_tracking": {
                    "type": "boolean",
                    "description": "Default click tracking for emails from this domain."
                  },
                  "tls": {
                    "type": "string",
                    "description": "Outbound encryption: opportunistic (default: encrypt whenever offered), required (TLS or no delivery) or verified (TLS with a valid certificate). Limits: other values → 422 invalid_parameter \"tls must be opportunistic, required or verified\""
                  },
                  "reply_tracking": {
                    "type": "boolean",
                    "description": "Default reply tracking for emails from this domain (override per email with tracking.replies). Limits: true without a reply_domain → 422 invalid_parameter \"reply_tracking needs a reply_domain: add an inbound domain such as reply.<domain> first\""
                  },
                  "reply_domain": {
                    "type": "string",
                    "description": "Where tracked reply addresses live: one of your inbound domains, MX-verified, equal to this domain or a subdomain of it (e.g. reply.acme.com). \"\" clears it. Limits: otherwise 422 invalid_parameter"
                  },
                  "reply_forward_to": {
                    "type": "string",
                    "description": "Where replies a person wrote are forwarded: a plain address on one of your verified domains, or a confirmed forward destination; never a receiving address. \"\" (default) forwards to the email’s first Reply-To, else its From. Limits: otherwise 422 invalid_parameter"
                  }
                }
              },
              "example": {
                "open_tracking": true,
                "click_tracking": true,
                "reply_domain": "reply.acme.com",
                "reply_tracking": true
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-domain",
        "summary": "Delete a domain",
        "description": "Delete a sending domain. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/domains/{id}/verify": {
      "post": {
        "operationId": "verify-domain",
        "summary": "Verify a domain",
        "description": "Check DKIM/SPF/DMARC DNS now and update the domain's status. Requires a full-access live key; test keys get 403 test_key_restricted. found shows, per DNS name, what is published right now. For the root domain only SPF-type TXT values are listed; a DMARC policy inherited from the parent domain is marked “(inherited from _dmarc.<domain>)”.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.verify",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                },
                "example": {
                  "id": "019a1f10-8a10-7b22-8c31-5d2e9f0a4b17",
                  "name": "acme.com",
                  "status": "verified",
                  "dkim_selector": "zap",
                  "dkim_verified": true,
                  "spf_verified": true,
                  "dmarc_verified": false,
                  "open_tracking": false,
                  "click_tracking": false,
                  "from_name": "",
                  "tls": "opportunistic",
                  "reply_tracking": false,
                  "reply_domain": "",
                  "reply_forward_to": "",
                  "brand_updated_at": null,
                  "last_checked_at": "2026-10-21T14:02:11Z",
                  "verified_at": "2026-10-21T14:02:11Z",
                  "created_at": "2026-10-21T13:58:02Z",
                  "zone": "acme.com",
                  "records": [
                    {
                      "record": "DKIM",
                      "type": "TXT",
                      "name": "zap._domainkey.acme.com",
                      "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...",
                      "required": true,
                      "status": "verified"
                    },
                    {
                      "record": "SPF",
                      "type": "TXT",
                      "name": "acme.com",
                      "value": "v=spf1 include:_spf.zapsmtp.xyz ~all",
                      "required": false,
                      "status": "verified"
                    },
                    {
                      "record": "DMARC",
                      "type": "TXT",
                      "name": "_dmarc.acme.com",
                      "value": "v=DMARC1; p=none;",
                      "required": false,
                      "status": "pending"
                    }
                  ],
                  "found": {
                    "zap._domainkey.acme.com": [
                      "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
                    ],
                    "acme.com": [
                      "v=spf1 include:_spf.zapsmtp.xyz ~all"
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict: this domain is already verified by another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/domains/{id}/reputation": {
      "get": {
        "operationId": "domain-reputation",
        "summary": "Domain reputation",
        "description": "Blocklist (DNSBL) status of a sending domain. Requires a full-access key. Customer domains are checked automatically every 6 hours (operator-configurable). The exact JSON for codes/labels when empty (null vs []) depends on the stored arrays; not verified.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.getReputation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainReputation"
                },
                "example": {
                  "object": "domain_reputation",
                  "domain": "acme.com",
                  "worst": "",
                  "lists": [
                    {
                      "target": "acme.com",
                      "kind": "domain",
                      "list": "spamhaus-dbl",
                      "name": "Spamhaus DBL",
                      "listed": false,
                      "severity": null,
                      "codes": [],
                      "labels": [],
                      "detail": "",
                      "error": null,
                      "listed_since": null,
                      "checked_at": "2026-10-21T12:00:03Z",
                      "removal_url": "https://check.spamhaus.org/"
                    },
                    {
                      "target": "acme.com",
                      "kind": "domain",
                      "list": "surbl",
                      "name": "SURBL",
                      "listed": false,
                      "severity": null,
                      "codes": [],
                      "labels": [],
                      "detail": "",
                      "error": null,
                      "listed_since": null,
                      "checked_at": "2026-10-21T12:00:03Z",
                      "removal_url": "https://www.surbl.org/surbl-analysis"
                    },
                    {
                      "target": "acme.com",
                      "kind": "domain",
                      "list": "uribl",
                      "name": "URIBL",
                      "listed": false,
                      "severity": null,
                      "codes": [],
                      "labels": [],
                      "detail": "",
                      "error": null,
                      "listed_since": null,
                      "checked_at": "2026-10-21T12:00:03Z",
                      "removal_url": "https://admin.uribl.com/"
                    }
                  ],
                  "events": [
                    {
                      "id": "019a1e00-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
                      "target": "acme.com",
                      "kind": "domain",
                      "list": "uribl",
                      "name": "URIBL",
                      "event": "delisted",
                      "severity": null,
                      "codes": [],
                      "detail": "",
                      "at": "2026-10-19T06:00:02Z"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/domains/{id}/dmarc": {
      "get": {
        "operationId": "domain-dmarc",
        "summary": "DMARC reports",
        "description": "DMARC aggregate reports about the domain: the address to publish in your DMARC record and what mailbox providers reported. Requires a full-access key. Add rua to your DMARC record (keep your policy). Providers send one report a day; reports are kept 400 days. ours marks ZapSMTP sending IPs: another IP that fails DMARC is a service you have not set up (add its DKIM/SPF) or someone spoofing your domain.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.getDmarc",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Domain id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "1-180; out-of-range falls back to 30.",
            "schema": {
              "type": "integer",
              "default": "30"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DmarcSummary"
                },
                "example": {
                  "object": "dmarc_summary",
                  "domain": "acme.com",
                  "days": 30,
                  "since": "2026-09-26T00:00:00Z",
                  "rua": "mailto:dmarc-k7x2m4q9p3a5b6c8@zapsmtp.xyz",
                  "record": {
                    "type": "TXT",
                    "name": "_dmarc.acme.com",
                    "value": "v=DMARC1; p=none; rua=mailto:dmarc-k7x2m4q9p3a5b6c8@zapsmtp.xyz"
                  },
                  "reports": 42,
                  "totals": {
                    "messages": 18240,
                    "passed": 18015,
                    "dkim_passed": 18001,
                    "spf_passed": 17890,
                    "quarantined": 190,
                    "rejected": 35
                  },
                  "sources": [
                    {
                      "ip": "192.0.2.10",
                      "messages": 18000,
                      "passed": 17990,
                      "dkim_passed": 17985,
                      "spf_passed": 17880,
                      "quarantined": 10,
                      "rejected": 0,
                      "reporters": [
                        "Yahoo",
                        "google.com"
                      ],
                      "ours": true
                    },
                    {
                      "ip": "203.0.113.5",
                      "messages": 240,
                      "passed": 25,
                      "dkim_passed": 16,
                      "spf_passed": 10,
                      "quarantined": 180,
                      "rejected": 35,
                      "reporters": [
                        "google.com"
                      ],
                      "ours": false
                    }
                  ],
                  "reporters": [
                    {
                      "org": "google.com",
                      "reports": 30,
                      "messages": 15400
                    },
                    {
                      "org": "Yahoo",
                      "reports": 12,
                      "messages": 2840
                    }
                  ],
                  "series": [
                    {
                      "day": "2026-10-24T00:00:00Z",
                      "messages": 640,
                      "passed": 632,
                      "dkim_passed": 632,
                      "spf_passed": 628,
                      "quarantined": 6,
                      "rejected": 2
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: Not a domain of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/domains/{id}/reputation/check": {
      "post": {
        "operationId": "check-domain-reputation",
        "summary": "Check reputation now",
        "description": "Run a blocklist check of the domain now and return its reputation. Requires a full-access live key; test keys get 403 test_key_restricted. At most once per minute per domain name. No Retry-After header is set.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.checkReputation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DomainReputation"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limit_exceeded: this domain was checked less than a minute ago",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/domains/{id}/brand": {
      "get": {
        "operationId": "get-brand",
        "summary": "Retrieve brand settings",
        "description": "Brand-in-the-inbox status: sender name, BIMI logo/certificate, DMARC enforcement and per-provider readiness. Requires a full-access key.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.getBrand",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Brand"
                },
                "example": {
                  "from_name": "Acme",
                  "logo_url": "https://zapsmtp.xyz/bimi/acme.com/logo.svg",
                  "cert_url": "",
                  "has_logo": true,
                  "has_cert": false,
                  "bimi_record": {
                    "record": "BIMI",
                    "type": "TXT",
                    "name": "default._bimi.acme.com",
                    "value": "v=BIMI1; l=https://zapsmtp.xyz/bimi/acme.com/logo.svg; a=;",
                    "required": false,
                    "status": "verified"
                  },
                  "dmarc_record": {
                    "record": "DMARC",
                    "type": "TXT",
                    "name": "_dmarc.acme.com",
                    "value": "v=DMARC1; p=quarantine; pct=100;",
                    "required": false,
                    "status": "verified"
                  },
                  "dmarc": {
                    "record": "v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc@acme.com",
                    "domain": "acme.com",
                    "p": "quarantine",
                    "sp": "",
                    "pct": 100,
                    "enforced": true
                  },
                  "published_bimi": "v=BIMI1; l=https://zapsmtp.xyz/bimi/acme.com/logo.svg; a=;",
                  "checks": [
                    {
                      "id": "auth",
                      "label": "SPF, DKIM and DMARC pass",
                      "ok": true,
                      "detail": "Domain verified; ZapSMTP signs every message with DKIM."
                    },
                    {
                      "id": "dmarc",
                      "label": "DMARC at enforcement",
                      "ok": true,
                      "detail": "Found on acme.com: v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc@acme.com"
                    },
                    {
                      "id": "logo",
                      "label": "Logo in SVG Tiny PS, hosted over HTTPS",
                      "ok": true,
                      "detail": "Square, ≤ 32 KB, solid background. Upload it below; we fix the profile automatically."
                    },
                    {
                      "id": "bimi",
                      "label": "BIMI record published",
                      "ok": true,
                      "detail": "default._bimi.acme.com points to the hosted logo. Mailbox providers may take up to 48 hours to show it."
                    },
                    {
                      "id": "cert",
                      "label": "Verified Mark Certificate (VMC) or Common Mark Certificate (CMC)",
                      "ok": false,
                      "detail": "Required by Gmail and Apple Mail (Gmail does not support a standalone SVG). VMC needs a registered trademark and adds the blue checkmark. Upload the PEM chain in order: certificate, intermediate, root."
                    },
                    {
                      "id": "name",
                      "label": "Sender name",
                      "ok": true,
                      "detail": "Used when an email's from has no display name, e.g. hello@ → \"Acme <hello@…>\"."
                    }
                  ],
                  "providers": {
                    "gmail": "needs_certificate",
                    "apple": "needs_certificate",
                    "yahoo": "ready"
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "update-brand",
        "summary": "Update brand settings",
        "description": "Set the default sender name and upload/remove the BIMI logo and certificate. Requires a full-access live key; test keys get 403 test_key_restricted. Hosted files are served publicly at /bimi/<domain>/logo.svg and /bimi/<domain>/cert.pem (outside /v1) for verified domains only.",
        "tags": [
          "Domains"
        ],
        "x-sdk-method": "domains.updateBrand",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Brand"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_certificate: \ninvalid_logo: \ninvalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "from_name": {
                    "type": "string",
                    "description": "Display name used when an email's from has only an address. \"\" clears it. Limits: max 70 characters, no < > \" or line breaks → 422 invalid_parameter"
                  },
                  "logo_svg": {
                    "type": "string",
                    "description": "SVG source; normalized to SVG Tiny PS (fixes reported in logo_fixed, warnings in logo_warnings). Limits: max 32 KB and valid SVG → otherwise 422 invalid_logo"
                  },
                  "cert_pem": {
                    "type": "string",
                    "description": "VMC/CMC PEM chain (certificate, intermediate, root). Limits: 422 invalid_certificate"
                  },
                  "remove_logo": {
                    "type": "boolean"
                  },
                  "remove_cert": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "from_name": "Acme"
              }
            }
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "operationId": "list-webhooks",
        "summary": "List webhooks",
        "description": "List webhook endpoints (newest first); secrets are omitted. Requires a full-access key. previous_secret_expires_at appears while a rotated secret still signs deliveries.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "019a1f22-6e7f-7091-8a2b-3c4d5e6f7a8b",
                      "url": "https://acme.com/hooks/zapsmtp",
                      "events": [
                        "email.delivered",
                        "email.bounced",
                        "email.complained"
                      ],
                      "enabled": true,
                      "disabled_reason": null,
                      "created_at": "2026-10-20T12:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-webhook",
        "summary": "Create a webhook",
        "description": "Create a webhook endpoint; the signing secret is returned. Requires a full-access live key; test keys get 403 test_key_restricted. The secret is also readable later via GET /webhooks/{id}. To send clicks of one button to this endpoint: {\"events\": [\"email.clicked\"], \"filter\": {\"actions\": [\"confirm_order\"]}}. Endpoints always return filter, with an empty list when there is none.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "id": "019a1f22-6e7f-7091-8a2b-3c4d5e6f7a8b",
                  "url": "https://acme.com/hooks/zapsmtp",
                  "secret": "whsec_Q7v2Lk9Xp4Rb1Tz8Mw3Nc6Hy0Fd5Gs2J",
                  "events": [
                    "email.delivered",
                    "email.bounced",
                    "email.complained"
                  ],
                  "enabled": true,
                  "disabled_reason": null,
                  "created_at": "2026-10-21T15:40:00Z",
                  "include_content": false,
                  "batch": false,
                  "filter": {
                    "actions": []
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Absolute https:// URL. Limits: 422 invalid_parameter \"url must be an absolute https:// URL\""
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Limits: unknown type → 422 invalid_parameter \"unknown event type <x>; allowed: ...\""
                  },
                  "include_content": {
                    "type": "boolean",
                    "description": "email.received carries the message: text, html, headers, and download links (valid 24 hours) for the attachments and the raw .eml; text and html are cut at 1 MB in total (truncated: true)."
                  },
                  "batch": {
                    "type": "boolean",
                    "description": "Send events up to 100 per request (or every second) as a JSON array, signed as one body; Zap-Event-Id is the batch id, each event keeps its own id. email.received with the full message still arrives alone."
                  },
                  "filter": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/WebhookFilter"
                      }
                    ],
                    "description": "Narrows email.clicked to some click actions; other event types are not affected. Empty or absent: every click."
                  }
                },
                "required": [
                  "url"
                ]
              },
              "example": {
                "url": "https://acme.com/hooks/zapsmtp",
                "events": [
                  "email.delivered",
                  "email.bounced",
                  "email.complained"
                ]
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}": {
      "get": {
        "operationId": "get-webhook",
        "summary": "Retrieve a webhook",
        "description": "Retrieve a webhook endpoint including its signing secret. Requires a full-access key.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "id": "019a1f22-6e7f-7091-8a2b-3c4d5e6f7a8b",
                  "url": "https://acme.com/hooks/zapsmtp",
                  "secret": "whsec_Q7v2Lk9Xp4Rb1Tz8Mw3Nc6Hy0Fd5Gs2J",
                  "previous_secret_expires_at": "2026-10-22T15:45:00Z",
                  "events": [
                    "email.delivered",
                    "email.bounced",
                    "email.complained"
                  ],
                  "enabled": true,
                  "disabled_reason": null,
                  "created_at": "2026-10-20T12:00:00Z",
                  "filter": {
                    "actions": []
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "update-webhook",
        "summary": "Update a webhook",
        "description": "Update a webhook's URL, events, click-action filter or enabled state. Requires a full-access live key; test keys get 403 test_key_restricted. The response's disabled_reason reflects the value before the update (the store clears it on re-enable but the returned object is not reloaded).",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "id": "019a1f22-6e7f-7091-8a2b-3c4d5e6f7a8b",
                  "url": "https://acme.com/hooks/zapsmtp-v2",
                  "events": [
                    "email.delivered"
                  ],
                  "enabled": true,
                  "disabled_reason": null,
                  "created_at": "2026-10-20T12:00:00Z",
                  "filter": {
                    "actions": []
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Limits: absolute https:// URL"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Limits: [] → 422 \"select at least one event\"; unknown type → 422 \"unknown event type <x>\""
                  },
                  "enabled": {
                    "type": "boolean",
                    "description": "Re-enabling clears disabled_reason. Disabling drops pending deliveries."
                  },
                  "include_content": {
                    "type": "boolean",
                    "description": "email.received carries the message: text, html, headers, and download links (valid 24 hours) for the attachments and the raw .eml; text and html are cut at 1 MB in total (truncated: true)."
                  },
                  "batch": {
                    "type": "boolean",
                    "description": "Send events up to 100 per request (or every second) as a JSON array, signed as one body; Zap-Event-Id is the batch id, each event keeps its own id. email.received with the full message still arrives alone."
                  },
                  "filter": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/WebhookFilter"
                      }
                    ],
                    "description": "Narrows email.clicked to some click actions; other event types are not affected. Empty or absent: every click. Replaces the whole filter; {\"actions\": []} removes it."
                  }
                }
              },
              "example": {
                "enabled": true
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-webhook",
        "summary": "Delete a webhook",
        "description": "Delete a webhook endpoint. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "operationId": "test-webhook",
        "summary": "Send a test event",
        "description": "Send a signed sample event to the endpoint now and report the result. Requires a full-access live key; test keys get 403 test_key_restricted. Test events are not retried. delivery.error is present when the attempt failed (e.g. \"HTTP 500\"); status_code is 0 on network errors. The test attempt is recorded in the delivery log.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.test",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestResult"
                },
                "example": {
                  "ok": true,
                  "delivery": {
                    "event_id": "evt_test_9Gk2Lq7Xv1Rb4Tz8",
                    "event_type": "email.delivered",
                    "attempt": 1,
                    "status_code": 200,
                    "duration_ms": 143,
                    "at": "2026-10-21T15:50:00.123Z",
                    "body": {
                      "id": "evt_test_9Gk2Lq7Xv1Rb4Tz8",
                      "type": "email.delivered",
                      "created_at": "2026-10-21T15:50:00.120Z",
                      "data": {
                        "email_id": "00000000-0000-0000-0000-000000000000",
                        "from": "Test <test@example.com>",
                        "to": "recipient@example.com",
                        "subject": "ZapSMTP webhook test",
                        "response": {
                          "code": 250,
                          "message": "OK (test event)"
                        }
                      }
                    }
                  },
                  "payload": {
                    "id": "evt_test_9Gk2Lq7Xv1Rb4Tz8",
                    "type": "email.delivered",
                    "created_at": "2026-10-21T15:50:00.120Z",
                    "data": {
                      "email_id": "00000000-0000-0000-0000-000000000000",
                      "from": "Test <test@example.com>",
                      "to": "recipient@example.com",
                      "subject": "ZapSMTP webhook test",
                      "response": {
                        "code": 250,
                        "message": "OK (test event)"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "email.sent",
                      "email.delivered",
                      "email.delivery_delayed",
                      "email.bounced",
                      "email.complained",
                      "email.failed",
                      "email.opened",
                      "email.clicked",
                      "email.suppressed",
                      "email.received",
                      "thread.created",
                      "thread.replied",
                      "email.replied"
                    ],
                    "description": "Limits: 422 invalid_parameter \"unknown event type\""
                  }
                }
              },
              "example": {
                "type": "email.delivered"
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/deliveries": {
      "get": {
        "operationId": "webhook-deliveries",
        "summary": "List delivery attempts",
        "description": "List the last 100 delivery attempts of a webhook (newest first). Requires a full-access key. attempt starts at 1. body is the exact payload sent (omitted above 64 KB); error is omitted on success.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.listDeliveries",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookDelivery"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "event_id": "evt_4f1c9a2b7e3d5c8a1b6f0e2d",
                      "event_type": "email.bounced",
                      "attempt": 2,
                      "status_code": 503,
                      "error": "HTTP 503",
                      "duration_ms": 412,
                      "at": "2026-10-21T15:09:17.004Z",
                      "body": {
                        "id": "evt_4f1c9a2b7e3d5c8a1b6f0e2d",
                        "type": "email.bounced",
                        "created_at": "2026-10-21T15:04:12.381Z",
                        "data": {
                          "email_id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23",
                          "to": "jane@example.org"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/events": {
      "get": {
        "operationId": "list-webhook-events",
        "summary": "List events",
        "description": "Events sent to this endpoint, newest first, each with its outcome and number of attempts (from the endpoint’s last 100 delivery attempts). Requires a full-access key.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.events.list",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEventRecord"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "object": "webhook_event",
                      "id": "evt_5f0c2a9b7d1e4c3a8b6f2e10",
                      "type": "email.delivered",
                      "status": "delivered",
                      "attempts": 2,
                      "last_status_code": 200,
                      "first_attempt_at": "2026-10-22T10:00:00Z",
                      "last_attempt_at": "2026-10-22T10:05:01Z"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/events/{event}": {
      "get": {
        "operationId": "get-webhook-event",
        "summary": "Retrieve an event",
        "description": "One event with its payload and every delivery attempt, oldest first. Requires a full-access key.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.events.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "event",
            "in": "path",
            "required": true,
            "description": "Event id (Zap-Event-Id).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookEventRecord"
                },
                "example": {
                  "object": "webhook_event",
                  "id": "evt_5f0c2a9b7d1e4c3a8b6f2e10",
                  "type": "email.delivered",
                  "status": "delivered",
                  "attempts": 2,
                  "last_status_code": 200,
                  "first_attempt_at": "2026-10-22T10:00:00Z",
                  "last_attempt_at": "2026-10-22T10:05:01Z",
                  "payload": {
                    "id": "evt_5f0c2a9b7d1e4c3a8b6f2e10",
                    "type": "email.delivered",
                    "created_at": "2026-10-22T09:59:59Z",
                    "data": {
                      "email_id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23",
                      "to": "jane@example.org"
                    }
                  },
                  "attempt_list": [
                    {
                      "attempt": 1,
                      "status_code": 503,
                      "error": "HTTP 503",
                      "duration_ms": 120,
                      "at": "2026-10-22T10:00:00Z"
                    },
                    {
                      "attempt": 2,
                      "status_code": 200,
                      "duration_ms": 85,
                      "at": "2026-10-22T10:05:01Z"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown webhook, or the event is not among the last 100 attempts.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/deliveries/{event}/replay": {
      "post": {
        "operationId": "replay-event",
        "summary": "Replay an event",
        "description": "Re-send a past event (from the last 100 deliveries) to the endpoint now. Requires a full-access live key; test keys get 403 test_key_restricted. Same body and Zap-Event-Id as the original, signed with the current secret(s) and a new timestamp. The replay is sent synchronously and not retried. Events whose body was over 64 KB cannot be replayed.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.events.replay",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "event",
            "in": "path",
            "required": true,
            "description": "Event id (evt_...) from GET /webhooks/{id}/deliveries",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestResult"
                },
                "example": {
                  "ok": true,
                  "delivery": {
                    "event_id": "evt_4f1c9a2b7e3d5c8a1b6f0e2d",
                    "event_type": "email.bounced",
                    "attempt": 3,
                    "status_code": 200,
                    "duration_ms": 98,
                    "at": "2026-10-21T16:00:00.512Z",
                    "body": {
                      "id": "evt_4f1c9a2b7e3d5c8a1b6f0e2d",
                      "type": "email.bounced",
                      "created_at": "2026-10-21T15:04:12.381Z",
                      "data": {
                        "email_id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23",
                        "to": "jane@example.org"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: webhook not found | event not found in the last 100 deliveries of this webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}/rotate-secret": {
      "post": {
        "operationId": "rotate-secret",
        "summary": "Rotate the signing secret",
        "description": "Generate a new signing secret; the old one stays valid for 24 hours. Requires a full-access live key; test keys get 403 test_key_restricted. During the grace period Zap-Signature carries two v1= entries (new secret first). Rotating again replaces the previous secret.",
        "tags": [
          "Webhooks"
        ],
        "x-sdk-method": "webhooks.rotateSecret",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Webhook id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                },
                "example": {
                  "object": "webhook",
                  "id": "019a1f22-6e7f-7091-8a2b-3c4d5e6f7a8b",
                  "secret": "whsec_R2m8Kx5Vq1Lb7Tn4Zw9Pc3Hj6Fd0Gs8Y",
                  "previous_secret_expires_at": "2026-10-22T15:45:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: webhook not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/actions": {
      "get": {
        "operationId": "list-actions",
        "summary": "List actions",
        "description": "List every action of the account: the ones you declared, the ones links named in the last 30 days, and the ones templates and webhook filters use. Sorted by name. Requires a full-access key. declared is false for an action that links use but nobody described; created_at and updated_at are then null. clicks_7d, clicks_30d and unique_clickers_30d (distinct email and recipient pairs) count the last 7 and 30 days; last_click_at is null without a click in 30 days. templates counts the templates whose draft or published HTML names the action; webhooks lists the ids of the endpoints filtered on it.",
        "tags": [
          "Click actions"
        ],
        "x-sdk-method": "actions.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Action"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "object": "action",
                      "name": "confirm_order",
                      "description": "Customer confirms the order from the receipt",
                      "declared": true,
                      "created_at": "2026-10-24T09:12:00Z",
                      "updated_at": "2026-10-24T09:12:00Z",
                      "clicks_7d": 42,
                      "clicks_30d": 180,
                      "unique_clickers_30d": 171,
                      "last_click_at": "2026-10-27T08:41:05Z",
                      "templates": 1,
                      "webhooks": [
                        "019a1c55-0d6e-7f21-8b3a-5e9d4c7b2a10"
                      ]
                    },
                    {
                      "object": "action",
                      "name": "track_parcel",
                      "description": "",
                      "declared": false,
                      "created_at": null,
                      "updated_at": null,
                      "clicks_7d": 12,
                      "clicks_30d": 64,
                      "unique_clickers_30d": 60,
                      "last_click_at": "2026-10-26T19:02:44Z",
                      "templates": 2,
                      "webhooks": []
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-action",
        "summary": "Declare an action",
        "description": "Declare an action and describe it. Optional: links work with any valid name, declared or not. Requires a full-access live key; test keys get 403 test_key_restricted. The response does not count activity: the stats are zero and templates is 0 here. Read them with GET /actions/{name}.",
        "tags": [
          "Click actions"
        ],
        "x-sdk-method": "actions.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Action"
                },
                "example": {
                  "object": "action",
                  "name": "confirm_order",
                  "description": "Customer confirms the order from the receipt",
                  "declared": true,
                  "created_at": "2026-10-24T09:12:00Z",
                  "updated_at": "2026-10-24T09:12:00Z",
                  "clicks_7d": 0,
                  "clicks_30d": 0,
                  "unique_clickers_30d": 0,
                  "last_click_at": null,
                  "templates": 0,
                  "webhooks": []
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict: an action with this name exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: bad name or description",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The name links carry in data-zap-action: lowercase letters, digits, _, . and -, starting with a letter or digit, up to 64 characters. Limits: other names → 422 invalid_parameter"
                  },
                  "description": {
                    "type": "string",
                    "description": "What the button does, for your team. Limits: at most 500 bytes → 422 invalid_parameter"
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "confirm_order",
                "description": "Customer confirms the order from the receipt"
              }
            }
          }
        }
      }
    },
    "/actions/{name}": {
      "get": {
        "operationId": "get-action",
        "summary": "Retrieve an action",
        "description": "Retrieve one action from the catalogue, with its activity and where it is used. Requires a full-access key.",
        "tags": [
          "Click actions"
        ],
        "x-sdk-method": "actions.get",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Action name, as written in data-zap-action.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Action"
                },
                "example": {
                  "object": "action",
                  "name": "confirm_order",
                  "description": "Customer confirms the order from the receipt",
                  "declared": true,
                  "created_at": "2026-10-24T09:12:00Z",
                  "updated_at": "2026-10-24T09:12:00Z",
                  "clicks_7d": 42,
                  "clicks_30d": 180,
                  "unique_clickers_30d": 171,
                  "last_click_at": "2026-10-27T08:41:05Z",
                  "templates": 1,
                  "webhooks": [
                    "019a1c55-0d6e-7f21-8b3a-5e9d4c7b2a10"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: action not found: not declared, not clicked in 30 days and used by no template or webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "update-action",
        "summary": "Describe an action",
        "description": "Change an action’s description. An action that links use but nobody declared is declared by this call. Requires a full-access live key; test keys get 403 test_key_restricted. Like create, the response carries zero stats; read them with GET /actions/{name}.",
        "tags": [
          "Click actions"
        ],
        "x-sdk-method": "actions.update",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Action name, as written in data-zap-action.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Action"
                },
                "example": {
                  "object": "action",
                  "name": "confirm_order",
                  "description": "Customer confirms an order from the receipt email",
                  "declared": true,
                  "created_at": "2026-10-24T09:12:00Z",
                  "updated_at": "2026-10-27T10:05:00Z",
                  "clicks_7d": 0,
                  "clicks_30d": 0,
                  "unique_clickers_30d": 0,
                  "last_click_at": null,
                  "templates": 0,
                  "webhooks": []
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: action not found (the name is not a valid action name)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: description: at most 500 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "description": {
                    "type": "string",
                    "description": "The new description; leaving it out sets it to empty. Limits: at most 500 bytes → 422 invalid_parameter"
                  }
                }
              },
              "example": {
                "description": "Customer confirms an order from the receipt email"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-action",
        "summary": "Delete an action",
        "description": "Delete an action’s declaration. Links that name it keep working: clicks are still tracked and still reach webhooks filtered on it. Requires a full-access live key; test keys get 403 test_key_restricted. While links or webhooks still use it, the action stays in the catalogue with declared: false.",
        "tags": [
          "Click actions"
        ],
        "x-sdk-method": "actions.delete",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "Action name, as written in data-zap-action.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                },
                "example": {
                  "object": "action",
                  "name": "confirm_order",
                  "deleted": true
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: action not found (not declared)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/templates": {
      "get": {
        "operationId": "list-templates",
        "summary": "List templates",
        "description": "List templates (most recently updated first). Requires a full-access key. variables are sample values for previews; variable_names lists the variables used in the subject and bodies.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Template"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "019a1f23-7f80-7192-8b3c-4d5e6f7a8b9c",
                      "name": "Receipt",
                      "alias": "receipt",
                      "subject": "Your receipt for {{order_id}}",
                      "html": "<p>Hi {{name}}, thanks for order {{order_id}}.</p>",
                      "text": "Hi {{name}}, thanks for order {{order_id}}.",
                      "from": "Acme <billing@acme.com>",
                      "variables": {
                        "name": "Jane",
                        "order_id": "A-1042"
                      },
                      "design": null,
                      "created_at": "2026-10-20T12:30:00Z",
                      "updated_at": "2026-10-21T09:00:00Z",
                      "object": "template",
                      "variable_names": [
                        "order_id",
                        "name"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-template",
        "summary": "Create a template",
        "description": "Create a template (logic-less Mustache). Requires a full-access live key; test keys get 403 test_key_restricted. Syntax: {{var}} escaped, {{{var}}} raw, {{#list}}…{{/list}} sections, {{^x}}…{{/x}} inverted sections. Exact ordering of variable_names is determined by the parser; the example order is illustrative. Body: html and text both empty → 422 missing_required_field; template syntax errors → 422 template_render_error \"<field>: <error>\"; a tag that is not a variable name ({{first name}}, {{#each items}}, {{> footer}}) → 422 template_render_error \"html: line L, column C: {{…}} is not a variable name: …\" variable_schema in the response is the saved list after discovery. A send is checked against the published copy, published.variable_schema.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                },
                "example": {
                  "id": "019a1f23-7f80-7192-8b3c-4d5e6f7a8b9c",
                  "name": "Receipt",
                  "alias": "receipt",
                  "subject": "Your receipt for {{order_id}}",
                  "html": "<p>Hi {{name}}, thanks for order {{order_id}}.</p>",
                  "text": "Hi {{name}}, thanks for order {{order_id}}.",
                  "from": "Acme <billing@acme.com>",
                  "variables": {
                    "name": "Jane",
                    "order_id": "A-1042"
                  },
                  "variable_schema": [
                    {
                      "name": "order_id",
                      "type": "string",
                      "required": true,
                      "example": "A-1042",
                      "description": "Order number shown to the customer"
                    },
                    {
                      "name": "name",
                      "type": "string",
                      "required": false,
                      "default": "there",
                      "example": "Jane"
                    }
                  ],
                  "design": null,
                  "created_at": "2026-10-21T16:10:00Z",
                  "updated_at": "2026-10-21T16:10:00Z",
                  "object": "template",
                  "variable_names": [
                    "order_id",
                    "name"
                  ],
                  "status": "draft",
                  "has_unpublished_changes": false,
                  "published_at": null,
                  "published": null
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict: a template with this alias already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: request body too large (over 4 MB)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "missing_required_field: \ninvalid_parameter: \ntemplate_render_error: template syntax error: \"<field>: <error>\"\ntemplate_render_error: a tag that is not a variable name, e.g. {{first name}}, {{#each items}}, {{> footer}}: \"html: line L, column C: {{…}} is not a variable name: letters, digits, _ and - (no spaces), parts joined with dots\"",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Limits: trimmed, 1-200 characters → 422 missing_required_field \"name is required (max 200 chars)\""
                  },
                  "alias": {
                    "type": "string",
                    "description": "Stable handle usable instead of the id (template.id in sends, /templates/{alias}). Limits: ^[a-z0-9][a-z0-9_-]{0,62}$ → 422 invalid_parameter; duplicate → 409 conflict"
                  },
                  "subject": {
                    "type": "string",
                    "description": "Mustache source."
                  },
                  "html": {
                    "type": "string",
                    "description": "At least one of html and text is required. Mustache source; {{var}} is HTML-escaped, {{{var}}} raw."
                  },
                  "text": {
                    "type": "string"
                  },
                  "from": {
                    "type": "string",
                    "description": "Default From used when a send omits from."
                  },
                  "variables": {
                    "type": "object",
                    "additionalProperties": {},
                    "description": "Sample variables used by previews. Never used for sending; a variable first found in the source takes its sample as example."
                  },
                  "variable_schema": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/VariableSpec"
                    },
                    "description": "Declares the template’s variables (see Variable schema). Replaces the declared list when given. On every save, names the source uses that the list lacks are added (their sample value as example): a section {{#x}} as optional any, a dotted {{x.y}} as a required object, any other name as a required any, never stricter than sends were before, and declared names the source no longer uses are kept with unused: true. Limits: at most 200 entries, no duplicates, defaults and examples of their type → 422 invalid_parameter \"variable_schema: <reason>\""
                  },
                  "design": {
                    "description": "The visual editor’s document (a JSON object with a numeric version), stored with the template. null makes it a code template. Changing html without sending design drops the design (it no longer describes the HTML). Limits: max 1 MB → 422 invalid_parameter \"design is larger than 1 MB\"; not an object with a numeric version → 422 invalid_parameter"
                  },
                  "publish": {
                    "type": "boolean",
                    "description": "Publish the result in the same call. Without it the template stays a draft and is not used for sending until published."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "Welcome",
                "alias": "welcome",
                "subject": "Welcome, {{first_name}}",
                "html": "<p>Hi {{first_name}}, your workspace is ready.</p>",
                "publish": true
              }
            }
          }
        }
      }
    },
    "/templates/{id}": {
      "get": {
        "operationId": "get-template",
        "summary": "Retrieve a template",
        "description": "Retrieve a template by id or alias. Requires a full-access key. id is what template.id takes when you send; the alias works too. published is the version sends use (null until the first publish). published.variable_schema is null for a template last published before variable schemas existed: its sends need every variable, as before, until it is published again.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id (UUID) or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                },
                "example": {
                  "id": "019a1f23-7f80-7192-8b3c-4d5e6f7a8b9c",
                  "name": "Receipt",
                  "alias": "receipt",
                  "subject": "Your receipt for {{order_id}}",
                  "html": "<p>Hi {{name}}, thanks for order {{order_id}}.</p>",
                  "text": "Hi {{name}}, thanks for order {{order_id}}.",
                  "from": "Acme <billing@acme.com>",
                  "variables": {
                    "name": "Jane",
                    "order_id": "A-1042"
                  },
                  "variable_schema": [
                    {
                      "name": "order_id",
                      "type": "string",
                      "required": true,
                      "example": "A-1042",
                      "description": "Order number shown to the customer"
                    },
                    {
                      "name": "name",
                      "type": "string",
                      "required": false,
                      "default": "there",
                      "example": "Jane"
                    }
                  ],
                  "design": null,
                  "created_at": "2026-10-21T16:10:00Z",
                  "updated_at": "2026-10-21T16:10:00Z",
                  "object": "template",
                  "variable_names": [
                    "order_id",
                    "name"
                  ],
                  "status": "published",
                  "has_unpublished_changes": false,
                  "published_at": "2026-10-21T16:12:00Z",
                  "published": {
                    "subject": "Your receipt for {{order_id}}",
                    "html": "<p>Hi {{name}}, thanks for order {{order_id}}.</p>",
                    "text": "Hi {{name}}, thanks for order {{order_id}}.",
                    "from": "Acme <billing@acme.com>",
                    "design": null,
                    "variable_schema": [
                      {
                        "name": "order_id",
                        "type": "string",
                        "required": true,
                        "example": "A-1042",
                        "description": "Order number shown to the customer"
                      },
                      {
                        "name": "name",
                        "type": "string",
                        "required": false,
                        "default": "there",
                        "example": "Jane"
                      }
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: template not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "update-template",
        "summary": "Update a template",
        "description": "Update a template (partial). Requires a full-access live key; test keys get 403 test_key_restricted. Fields left out keep their value; the same validation as create applies to the result. Every save (and publish) is kept in the version history: see List versions. has_unpublished_changes is also true when only the draft’s variable_schema differs from the published one.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: template not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict: a template with this alias already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: request body too large (over 4 MB)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "missing_required_field: \ninvalid_parameter: \ntemplate_render_error: template syntax error: \"<field>: <error>\"\ntemplate_render_error: a tag that is not a variable name, e.g. {{first name}}, {{#each items}}, {{> footer}}: \"html: line L, column C: {{…}} is not a variable name: letters, digits, _ and - (no spaces), parts joined with dots\"",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Limits: trimmed, 1-200 characters → 422 missing_required_field \"name is required (max 200 chars)\""
                  },
                  "alias": {
                    "type": "string",
                    "description": "Stable handle; \"\" removes it usable instead of the id (template.id in sends, /templates/{alias}). Limits: ^[a-z0-9][a-z0-9_-]{0,62}$ → 422 invalid_parameter; duplicate → 409 conflict"
                  },
                  "subject": {
                    "type": "string",
                    "description": "Mustache source."
                  },
                  "html": {
                    "type": "string",
                    "description": "Mustache source; {{var}} is HTML-escaped, {{{var}}} raw."
                  },
                  "text": {
                    "type": "string"
                  },
                  "from": {
                    "type": "string",
                    "description": "Default From used when a send omits from."
                  },
                  "variables": {
                    "type": "object",
                    "additionalProperties": {},
                    "description": "Sample variables used by previews; replaces the whole object. Never used for sending; a variable first found in the source takes its sample as example."
                  },
                  "variable_schema": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/VariableSpec"
                    },
                    "description": "Declares the template’s variables (see Variable schema). Replaces the declared list when given. On every save, names the source uses that the list lacks are added (their sample value as example): a section {{#x}} as optional any, a dotted {{x.y}} as a required object, any other name as a required any, never stricter than sends were before, and declared names the source no longer uses are kept with unused: true. Limits: at most 200 entries, no duplicates, defaults and examples of their type → 422 invalid_parameter \"variable_schema: <reason>\""
                  },
                  "design": {
                    "description": "The visual editor’s document (a JSON object with a numeric version), stored with the template. null makes it a code template. Changing html without sending design drops the design (it no longer describes the HTML). Limits: max 1 MB → 422 invalid_parameter \"design is larger than 1 MB\"; not an object with a numeric version → 422 invalid_parameter"
                  },
                  "publish": {
                    "type": "boolean",
                    "description": "Publish the result in the same call. Without it the template stays a draft and is not used for sending until published."
                  }
                }
              },
              "example": {
                "subject": "Welcome aboard, {{first_name}}"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-template",
        "summary": "Delete a template",
        "description": "Delete a template. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                },
                "example": {
                  "object": "template",
                  "id": "019a1f23-7f80-7192-8b3c-4d5e6f7a8b9c",
                  "deleted": true
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: template not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}/publish": {
      "post": {
        "operationId": "publish-template",
        "summary": "Publish a template",
        "description": "Make the current draft the version sends use. Until a template is published, sending with it fails. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.publish",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id or alias.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                },
                "example": {
                  "object": "template",
                  "id": "019a1f50-1c2d-7e3f-8a4b-5c6d7e8f9a0b",
                  "name": "Welcome",
                  "alias": "welcome",
                  "subject": "Welcome, {{first_name}}",
                  "html": "<p>Hi {{first_name}}</p>",
                  "text": "",
                  "from": "",
                  "design": null,
                  "status": "published",
                  "has_unpublished_changes": false,
                  "published_at": "2026-10-22T15:10:00Z",
                  "published": {
                    "subject": "Welcome, {{first_name}}",
                    "html": "<p>Hi {{first_name}}</p>",
                    "text": "",
                    "from": "",
                    "design": null
                  },
                  "variable_names": [
                    "first_name"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "test_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown template.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}/duplicate": {
      "post": {
        "operationId": "duplicate-template",
        "summary": "Duplicate a template",
        "description": "Copy a template’s draft into a new, unpublished template named “… (copy)”, without the alias. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.duplicate",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id or alias.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                },
                "example": {
                  "object": "template",
                  "id": "019a1f52-3e4f-7a5b-8c6d-7e8f9a0b1c2d",
                  "name": "Welcome (copy)",
                  "alias": null,
                  "status": "draft",
                  "has_unpublished_changes": false,
                  "published_at": null,
                  "published": null
                }
              }
            }
          },
          "403": {
            "description": "test_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown template.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}/render": {
      "post": {
        "operationId": "render-template",
        "summary": "Render a template",
        "description": "Preview a stored template with given variables (defaults to its sample variables). Requires a full-access key. Missing variables do not fail the preview; they are listed in missing_variables.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.render",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id or alias",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderedTemplate"
                },
                "example": {
                  "subject": "Your receipt for A-1042",
                  "html": "<p>Hi Jane, thanks for order A-1042.</p>",
                  "text": "Hi Jane, thanks for order A-1042.",
                  "missing_variables": [],
                  "variable_names": [
                    "order_id",
                    "name"
                  ],
                  "design": null
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: template not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "template_render_error: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "variables": {
                    "type": "object",
                    "additionalProperties": {},
                    "description": "Variables to render with; when omitted the template's stored sample variables are used."
                  }
                }
              },
              "example": {
                "variables": {
                  "first_name": "Ann"
                }
              }
            }
          }
        }
      }
    },
    "/templates/render": {
      "post": {
        "operationId": "render-source",
        "summary": "Render unsaved source",
        "description": "Validate and preview unsaved template source. Requires a full-access key.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.renderSource",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RenderedTemplate"
                },
                "example": {
                  "subject": "Hello Jane",
                  "html": "<p>Welcome, Jane!</p>",
                  "text": "",
                  "missing_variables": [
                    "plan"
                  ],
                  "variable_names": [
                    "name",
                    "plan"
                  ],
                  "design": null
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "template_render_error: <field>: <syntax error>",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subject": {
                    "type": "string"
                  },
                  "html": {
                    "type": "string"
                  },
                  "text": {
                    "type": "string"
                  },
                  "variables": {
                    "type": "object",
                    "additionalProperties": {}
                  }
                }
              },
              "example": {
                "subject": "Hi {{first_name}}",
                "html": "<p>Hello {{first_name}}</p>",
                "variables": {
                  "first_name": "Ann"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}/versions": {
      "get": {
        "operationId": "list-template-versions",
        "summary": "List versions",
        "description": "List a template’s saved versions, newest first. Requires a full-access key. A version is recorded on every create, update, publish and restore: kind is saved, published or restored. author is the teammate’s email, or API key. The newest 50 versions are kept. List items leave out the bodies; retrieve a version for them.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.versions.list",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id or alias.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TemplateVersion"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "019a1f5a-3d4e-7f50-9a61-7b8c9d0e1f2a",
                      "kind": "published",
                      "author": "API key",
                      "name": "Welcome",
                      "subject": "Welcome, {{first_name}}",
                      "created_at": "2026-10-22T15:10:00Z"
                    },
                    {
                      "id": "019a1f58-2b3c-7d4e-8f50-6a7b8c9d0e1f",
                      "kind": "saved",
                      "author": "jane@acme.com",
                      "name": "Welcome",
                      "subject": "Welcome, {{first_name}}",
                      "created_at": "2026-10-22T14:52:00Z"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: template not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}/versions/{vid}": {
      "get": {
        "operationId": "get-template-version",
        "summary": "Retrieve a version",
        "description": "Retrieve one version with its bodies and design. Requires a full-access key. Empty html, text and from are left out, and so is design for a code template.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.versions.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id or alias.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "vid",
            "in": "path",
            "required": true,
            "description": "Version id from the list.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateVersion"
                },
                "example": {
                  "id": "019a1f58-2b3c-7d4e-8f50-6a7b8c9d0e1f",
                  "kind": "saved",
                  "author": "jane@acme.com",
                  "name": "Welcome",
                  "subject": "Welcome, {{first_name}}",
                  "html": "<p>Hi {{first_name}}, welcome to Acme.</p>",
                  "text": "Hi {{first_name}}, welcome to Acme.",
                  "from": "Acme <hello@acme.com>",
                  "created_at": "2026-10-22T14:52:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: template not found | version not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{id}/versions/{vid}/restore": {
      "post": {
        "operationId": "restore-template-version",
        "summary": "Restore a version",
        "description": "Copy a version back into the draft. Publishing stays a separate step. Requires a full-access live key; test keys get 403 test_key_restricted. Restores name, subject, html, text, from and design; alias and sample variables stay. The restore is recorded as a version of kind restored. Sends keep using the published version until you publish.",
        "tags": [
          "Templates"
        ],
        "x-sdk-method": "templates.versions.restore",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Template id or alias.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "vid",
            "in": "path",
            "required": true,
            "description": "Version id from the list.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                },
                "example": {
                  "id": "019a1f50-1c2d-7e3f-8a4b-5c6d7e8f9a0b",
                  "name": "Welcome",
                  "alias": "welcome",
                  "subject": "Welcome, {{first_name}}",
                  "html": "<p>Hi {{first_name}}, welcome to Acme.</p>",
                  "text": "Hi {{first_name}}, welcome to Acme.",
                  "from": "Acme <hello@acme.com>",
                  "variables": {
                    "first_name": "Ann"
                  },
                  "design": null,
                  "created_at": "2026-10-20T12:30:00Z",
                  "updated_at": "2026-10-22T15:20:00Z",
                  "published": {
                    "subject": "Welcome, {{first_name}}",
                    "html": "<p>Hi {{first_name}}</p>",
                    "text": "",
                    "from": "",
                    "design": null
                  },
                  "published_at": "2026-10-22T15:10:00Z",
                  "object": "template",
                  "status": "published",
                  "has_unpublished_changes": true,
                  "variable_names": [
                    "first_name"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: template not found | version not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/variables": {
      "get": {
        "operationId": "list-variables",
        "summary": "List variables",
        "description": "The variable catalogue: every variable the account’s templates can use, with where each is used. System variables first, then global ones, then template variables, each sorted by name. Requires a full-access key. kind is system (filled by ZapSMTP), global (set for the account, written {{global.key}}) or template (a template’s own). A global variable that templates use but that has no value yet is listed without value; sends with those templates fail until you set it. A template variable lists in types every type its templates declare, and per template its type, required, default and unused (declared, but the source no longer names it).",
        "tags": [
          "Variables"
        ],
        "x-sdk-method": "variables.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Variable"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "object": "variable",
                      "name": "zap:unsubscribe_url",
                      "kind": "system",
                      "type": "url",
                      "description": "The recipient's one-click unsubscribe link (also adds List-Unsubscribe).",
                      "templates": []
                    },
                    {
                      "object": "variable",
                      "name": "global.company_name",
                      "kind": "global",
                      "type": "string",
                      "key": "company_name",
                      "value": "Acme Inc.",
                      "description": "Legal name for footers",
                      "updated_at": "2026-10-25T14:20:00Z",
                      "templates": [
                        {
                          "id": "019a1f23-7f80-7192-8b3c-4d5e6f7a8b9c",
                          "name": "Receipt"
                        }
                      ]
                    },
                    {
                      "object": "variable",
                      "name": "global.support_url",
                      "kind": "global",
                      "type": "string",
                      "key": "support_url",
                      "templates": [
                        {
                          "id": "019a1f23-7f80-7192-8b3c-4d5e6f7a8b9c",
                          "name": "Receipt"
                        }
                      ]
                    },
                    {
                      "object": "variable",
                      "name": "coupon",
                      "kind": "template",
                      "types": [
                        "object"
                      ],
                      "templates": [
                        {
                          "id": "019a1f23-7f80-7192-8b3c-4d5e6f7a8b9c",
                          "name": "Receipt",
                          "type": "object"
                        }
                      ]
                    },
                    {
                      "object": "variable",
                      "name": "order_id",
                      "kind": "template",
                      "types": [
                        "string"
                      ],
                      "description": "Order number shown to the customer",
                      "templates": [
                        {
                          "id": "019a1f23-7f80-7192-8b3c-4d5e6f7a8b9c",
                          "name": "Receipt",
                          "type": "string",
                          "required": true
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/variables/global/{key}": {
      "put": {
        "operationId": "put-global-variable",
        "summary": "Set a global variable",
        "description": "Create or replace a global variable. Every template that uses it renders the new value from the next send on. Requires a full-access live key; test keys get 403 test_key_restricted. The response does not list the templates using the variable; GET /variables does.",
        "tags": [
          "Variables"
        ],
        "x-sdk-method": "variables.setGlobal",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "The key, used as {{global.key}}: letters, digits, _ and -, starting with a letter or _, up to 64; global is reserved. Limits: other keys → 422 invalid_parameter",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Variable"
                },
                "example": {
                  "object": "variable",
                  "name": "global.company_name",
                  "kind": "global",
                  "type": "string",
                  "key": "company_name",
                  "value": "Acme Inc.",
                  "description": "Legal name for footers",
                  "updated_at": "2026-10-27T10:30:00Z",
                  "templates": []
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: bad key, value over 10 KB or description over 500 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "The value, always a string. Limits: at most 10 KB → 422 invalid_parameter"
                  },
                  "description": {
                    "type": "string",
                    "description": "What it is for. Limits: at most 500 bytes → 422 invalid_parameter"
                  }
                }
              },
              "example": {
                "value": "Acme Inc.",
                "description": "Legal name for footers"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-global-variable",
        "summary": "Delete a global variable",
        "description": "Delete a global variable. Sends with a template that still uses it then fail with 422 template_render_error until it is set again. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Variables"
        ],
        "x-sdk-method": "variables.deleteGlobal",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "description": "The key, used as {{global.key}}: letters, digits, _ and -, starting with a letter or _, up to 64; global is reserved. Limits: other keys → 422 invalid_parameter",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                },
                "example": {
                  "object": "variable",
                  "name": "global.company_name",
                  "deleted": true
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: global variable not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/template-modules": {
      "get": {
        "operationId": "list-template-modules",
        "summary": "List modules",
        "description": "List saved modules (reusable rows for the visual editor), most recently updated first. Requires a full-access key. All modules of the account in one page (has_more is always false).",
        "tags": [
          "Modules, images & timers"
        ],
        "x-sdk-method": "templateModules.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TemplateModule"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "019a1f61-4e5f-7a60-8b71-8c9d0e1f2a3b",
                      "name": "Footer",
                      "category": "Brand",
                      "design": {
                        "rows": [
                          {
                            "id": "r1",
                            "columns": [
                              {
                                "id": "c1",
                                "width": 100,
                                "blocks": [
                                  {
                                    "id": "b1",
                                    "type": "text",
                                    "html": "<p>Acme Inc. · 1 Market St, San Francisco</p>"
                                  }
                                ]
                              }
                            ]
                          }
                        ]
                      },
                      "created_at": "2026-10-22T16:00:00Z",
                      "updated_at": "2026-10-22T16:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-template-module",
        "summary": "Save a module",
        "description": "Save rows as a module that every template of the account can insert. Requires a full-access live key; test keys get 403 test_key_restricted. Inserting a module copies its rows into the template: changing the module later does not change templates that already use it.",
        "tags": [
          "Modules, images & timers"
        ],
        "x-sdk-method": "templateModules.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateModule"
                },
                "example": {
                  "id": "019a1f61-4e5f-7a60-8b71-8c9d0e1f2a3b",
                  "name": "Footer",
                  "category": "Brand",
                  "design": {
                    "rows": [
                      {
                        "id": "r1",
                        "columns": [
                          {
                            "id": "c1",
                            "width": 100,
                            "blocks": [
                              {
                                "id": "b1",
                                "type": "text",
                                "html": "<p>Acme Inc. · 1 Market St, San Francisco</p>"
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  },
                  "created_at": "2026-10-22T16:00:00Z",
                  "updated_at": "2026-10-22T16:00:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: request body too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: design must be {\"rows\": [...]} with at least one row (max 1 MB)\nmissing_required_field: name is required (max 200 chars), category max 100 chars",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Limits: trimmed, 1-200 characters → 422 missing_required_field"
                  },
                  "category": {
                    "type": "string",
                    "description": "Groups modules in the editor’s palette. Limits: trimmed, max 100 characters → 422 missing_required_field"
                  },
                  "design": {
                    "description": "The saved rows: {\"rows\": [...]} with at least one row in the visual editor’s format (copy rows from a template’s design). Limits: max 1 MB → 422 invalid_parameter"
                  }
                },
                "required": [
                  "name",
                  "design"
                ]
              },
              "example": {
                "name": "Footer",
                "category": "Brand",
                "design": {
                  "rows": [
                    {
                      "id": "r1",
                      "columns": [
                        {
                          "id": "c1",
                          "width": 100,
                          "blocks": [
                            {
                              "id": "b1",
                              "type": "text",
                              "html": "<p>Acme Inc. · 1 Market St, San Francisco</p>"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/template-modules/{id}": {
      "get": {
        "operationId": "get-template-module",
        "summary": "Retrieve a module",
        "description": "Retrieve a module. Requires a full-access key.",
        "tags": [
          "Modules, images & timers"
        ],
        "x-sdk-method": "templateModules.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Module id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateModule"
                },
                "example": {
                  "id": "019a1f61-4e5f-7a60-8b71-8c9d0e1f2a3b",
                  "name": "Footer",
                  "category": "Brand",
                  "design": {
                    "rows": [
                      {
                        "id": "r1",
                        "columns": [
                          {
                            "id": "c1",
                            "width": 100,
                            "blocks": [
                              {
                                "id": "b1",
                                "type": "text",
                                "html": "<p>Acme Inc. · 1 Market St, San Francisco</p>"
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  },
                  "created_at": "2026-10-22T16:00:00Z",
                  "updated_at": "2026-10-22T16:00:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: module not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "update-template-module",
        "summary": "Update a module",
        "description": "Rename, recategorize or replace a module’s rows. Requires a full-access live key; test keys get 403 test_key_restricted. Fields left out keep their value.",
        "tags": [
          "Modules, images & timers"
        ],
        "x-sdk-method": "templateModules.update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Module id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateModule"
                },
                "example": {
                  "id": "019a1f61-4e5f-7a60-8b71-8c9d0e1f2a3b",
                  "name": "Footer",
                  "category": "Footers",
                  "design": {
                    "rows": [
                      {
                        "id": "r1",
                        "columns": [
                          {
                            "id": "c1",
                            "width": 100,
                            "blocks": [
                              {
                                "id": "b1",
                                "type": "text",
                                "html": "<p>Acme Inc. · 1 Market St, San Francisco</p>"
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  },
                  "created_at": "2026-10-22T16:00:00Z",
                  "updated_at": "2026-10-23T09:30:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: module not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: request body too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: design must be {\"rows\": [...]} with at least one row (max 1 MB)\nmissing_required_field: name is required (max 200 chars), category max 100 chars",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Limits: trimmed, 1-200 characters → 422 missing_required_field"
                  },
                  "category": {
                    "type": "string",
                    "description": "Groups modules in the editor’s palette. Limits: trimmed, max 100 characters → 422 missing_required_field"
                  },
                  "design": {
                    "description": "The saved rows: {\"rows\": [...]} with at least one row in the visual editor’s format (copy rows from a template’s design). Limits: max 1 MB → 422 invalid_parameter"
                  }
                }
              },
              "example": {
                "category": "Footers"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-template-module",
        "summary": "Delete a module",
        "description": "Delete a module. Templates that inserted it keep their copy. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Modules, images & timers"
        ],
        "x-sdk-method": "templateModules.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Module id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                },
                "example": {
                  "object": "template_module",
                  "id": "019a1f61-4e5f-7a60-8b71-8c9d0e1f2a3b",
                  "deleted": true
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: module not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/template-assets": {
      "get": {
        "operationId": "list-template-assets",
        "summary": "List images",
        "description": "List the account’s template images, newest first. Requires a full-access key. All images of the account in one page (has_more is always false).",
        "tags": [
          "Modules, images & timers"
        ],
        "x-sdk-method": "templateAssets.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TemplateAsset"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "5b0e3c1a-9d2f-4e7b-8a61-2f4c6d8e0a13",
                      "name": "logo.png",
                      "ext": "png",
                      "content_type": "image/png",
                      "size": 18342,
                      "width": 480,
                      "height": 120,
                      "created_at": "2026-10-22T16:10:00Z",
                      "object": "template_asset",
                      "url": "https://zapsmtp.xyz/i/5b0e3c1a-9d2f-4e7b-8a61-2f4c6d8e0a13.png"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "upload-template-asset",
        "summary": "Upload an image",
        "description": "Upload an image for use in templates, as a multipart file or by URL; returns its public URL. Requires a full-access live key; test keys get 403 test_key_restricted. PNG, JPEG, GIF or WebP, up to 5 MB and 40 megapixels; the file content decides the type, not its name. PNG and JPEG images wider than 1,200 px are scaled down to 1,200 px (twice a 600 px email); GIF (animations included) and WebP are kept as they are. width and height are those of the stored image. The URL is public (anyone with it can load the image) and long-lived: use it in <img src> of any template. The name keeps letters, digits, spaces and . _ ( ) -, up to 200 characters. Each account holds up to 2,000 images and 1 GB.",
        "tags": [
          "Modules, images & timers"
        ],
        "x-sdk-method": "templateAssets.upload",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateAsset"
                },
                "example": {
                  "id": "5b0e3c1a-9d2f-4e7b-8a61-2f4c6d8e0a13",
                  "name": "logo.png",
                  "ext": "png",
                  "content_type": "image/png",
                  "size": 18342,
                  "width": 480,
                  "height": 120,
                  "created_at": "2026-10-22T16:10:00Z",
                  "object": "template_asset",
                  "url": "https://zapsmtp.xyz/i/5b0e3c1a-9d2f-4e7b-8a61-2f4c6d8e0a13.png"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: images are limited to 5 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_image: only PNG, JPEG, GIF and WebP images are accepted | image dimensions are too large | images are limited to 5 MB | the image could not be decoded\ninvalid_parameter: send the image as multipart field \"file\", or JSON {\"url\": \"...\"} | url must be an http(s) URL | fetching url returned HTTP <n> | could not fetch url: <reason> | the image at url is over 5 MB\nquota_exceeded: image library is full (2,000 images or 1 GB): delete unused images first",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "storage_unavailable: object storage is not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "JSON upload: an http(s) URL we download the image from (private and internal addresses are refused). Limits: unreachable, not HTTP 200 or not a URL → 422 invalid_parameter"
                  },
                  "name": {
                    "type": "string",
                    "description": "JSON upload: the file name shown in the image library."
                  }
                },
                "required": [
                  "url"
                ]
              },
              "example": {
                "url": "https://acme.com/brand/logo.png",
                "name": "logo.png"
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/template-assets/{id}": {
      "delete": {
        "operationId": "delete-template-asset",
        "summary": "Delete an image",
        "description": "Delete an image. Its URL stops working, also in emails already sent. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Modules, images & timers"
        ],
        "x-sdk-method": "templateAssets.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Image id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                },
                "example": {
                  "object": "template_asset",
                  "id": "5b0e3c1a-9d2f-4e7b-8a61-2f4c6d8e0a13",
                  "deleted": true
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: image not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/template-timers": {
      "post": {
        "operationId": "create-template-timer",
        "summary": "Create a countdown timer",
        "description": "Create a countdown timer image: an animated GIF that shows the time left whenever the email is opened. Requires a full-access live key; test keys get 403 test_key_restricted. Nothing is stored: the URL carries the signed settings, so changing it breaks the image. Put it in an <img> of a template (the visual editor’s timer block does this for you). Each open renders one frame per second for a minute, then the last frame stays; after end it shows zeros. Renders are shared for 5 seconds, so a broadcast opened by many recipients at once costs one render.",
        "tags": [
          "Modules, images & timers"
        ],
        "x-sdk-method": "templateTimers.create",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateTimer"
                },
                "example": {
                  "object": "template_timer",
                  "url": "https://zapsmtp.xyz/i/timer.gif?bg=ffffff&end=1795910399&fg=111827&l=days%7Chours%7Cminutes%7Cseconds&lc=6b7280&w=600&sig=Hk3x9vQm2LrT8aWc"
                }
              }
            }
          },
          "400": {
            "description": "validation_error: invalid JSON body (e.g. end not RFC 3339)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: see the fields",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "end": {
                    "type": "string",
                    "description": "When the countdown reaches zero. Limits: missing → 422 invalid_parameter \"end is required\"; not RFC 3339 → 400 validation_error"
                  },
                  "width": {
                    "type": "integer",
                    "description": "Image width in px, 200-600; the height follows. Limits: otherwise 422 invalid_parameter \"w must be 200–600\""
                  },
                  "digit_color": {
                    "type": "string",
                    "description": "Digit colour, hex RRGGBB or RRGGBBAA (a leading # is allowed). Limits: otherwise 422 invalid_parameter \"fg: colour must be RRGGBB or RRGGBBAA\""
                  },
                  "label_color": {
                    "type": "string",
                    "description": "Label colour, same format. Limits: 422 invalid_parameter \"lc: …\""
                  },
                  "background": {
                    "type": "string",
                    "description": "Background colour, same format; alpha 00 (e.g. ffffff00) is transparent. Limits: 422 invalid_parameter \"bg: …\""
                  },
                  "labels": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Exactly 4 labels under days, hours, minutes and seconds, each up to 12 characters, without |. \"\" hides one label; four empty labels hide the label row. Limits: 422 invalid_parameter \"l must hold 4 labels separated by |\" / \"labels are limited to 12 characters\""
                  }
                },
                "required": [
                  "end",
                  "digit_color",
                  "label_color",
                  "background"
                ]
              },
              "example": {
                "end": "2026-11-28T23:59:59Z",
                "digit_color": "111827",
                "label_color": "6b7280",
                "background": "ffffff"
              }
            }
          }
        }
      }
    },
    "/emails/receiving": {
      "get": {
        "operationId": "list-received",
        "summary": "List received emails",
        "description": "List received (inbound) emails, newest first. Requires a full-access key. action is default, webhook, store, reject or spam_reject. in_reply_to_email_id appears only when the message replies to an email you sent through ZapSMTP.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "emails.receiving.list",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-100; out-of-range falls back to 20.",
            "schema": {
              "type": "integer",
              "default": "20"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Cursor: an email id or RFC 3339 time; returns messages received before it. An email id gives an exact page boundary. Limits: 422 invalid_parameter \"before must be an email id or RFC 3339 time\"",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Email id or RFC 3339 time. Limits: 422 invalid_parameter \"after must be an email id or RFC 3339 time\"",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Case-insensitive substring of sender, recipient or subject, or an exact id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "",
            "schema": {
              "type": "string",
              "enum": [
                "received",
                "rejected"
              ]
            }
          },
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "description": "Inbound domain name (exact).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "thread_id",
            "in": "query",
            "required": false,
            "description": "Only emails of this conversation (see GET /threads/{id}).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "automated",
            "in": "query",
            "required": false,
            "description": "false: only emails a person wrote; true: only automated ones; or one type: bounce, out_of_office, auto_reply, auto_generated, bulk. Limits: 422 invalid_parameter for other values.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ReceivedEmail"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "object": "email",
                      "id": "019a1f30-1d4e-7a6b-8c2d-3e4f5a6b7c8d",
                      "from": "jane@example.org",
                      "from_name": "Jane Doe",
                      "to": [
                        "support@acme.com"
                      ],
                      "cc": [],
                      "bcc": [],
                      "reply_to": [],
                      "received_for": [
                        "support+1234@acme.com"
                      ],
                      "subject": "Re: Ticket #1234",
                      "message_id": "<CAF=abc123@mail.example.org>",
                      "created_at": "2026-10-21T15:10:02.904Z",
                      "attachments": [
                        {
                          "id": "5b0f8f7e-2a1c-5d3e-9f4a-6b7c8d9e0f1a",
                          "filename": "screenshot.png",
                          "content_type": "image/png",
                          "content_disposition": "attachment",
                          "content_id": null,
                          "size": 48213
                        }
                      ],
                      "status": "received",
                      "action": "webhook",
                      "is_spam": false,
                      "spam_score": 1.2,
                      "size": 61877,
                      "in_reply_to_email_id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "inbound_not_configured: inbound email is not enabled on this deployment",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/receiving/{id}": {
      "get": {
        "operationId": "get-received",
        "summary": "Retrieve a received email",
        "description": "Retrieve a received email with bodies, headers, authentication results and download links. Requires a full-access key. automated is null for mail a person wrote, else {type, reason}: bounce (delivery status notification), out_of_office, auto_reply, auto_generated (notifications, null sender) or bulk (mailing lists). Detected from Auto-Submitted, X-Autoreply, Precedence, List-Id, multipart/report and well-known subjects; reason names the evidence. tls: the TLS version the sending server used (e.g. TLSv1_3); empty when the message was not encrypted.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "emails.receiving.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Received email id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "html_format",
            "in": "query",
            "required": false,
            "description": "cid: return html as received (cid: references to inline parts). Any other value: inline images are embedded as data: URIs (html_format in the response reports what was returned).",
            "schema": {
              "type": "string",
              "enum": [
                "data_uri",
                "cid"
              ],
              "default": "data_uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceivedEmail"
                },
                "example": {
                  "object": "email",
                  "id": "019a1f30-1d4e-7a6b-8c2d-3e4f5a6b7c8d",
                  "created_at": "2026-10-21T15:10:02.904Z",
                  "from": "jane@example.org",
                  "to": [
                    "support@acme.com"
                  ],
                  "cc": [],
                  "bcc": [],
                  "reply_to": [],
                  "received_for": [
                    "support+1234@acme.com"
                  ],
                  "subject": "Re: Ticket #1234",
                  "message_id": "<CAF=abc123@mail.example.org>",
                  "html": "<p>Thanks, that fixed it!</p><blockquote>...</blockquote>",
                  "html_format": "data_uri",
                  "text": "Thanks, that fixed it!\n\nOn Tue, Oct 21, 2026 Acme wrote:\n> ...",
                  "headers": {
                    "Subject": "Re: Ticket #1234",
                    "From": "Jane Doe <jane@example.org>",
                    "To": "support@acme.com"
                  },
                  "authentication": {
                    "spf": "pass",
                    "dkim": "pass",
                    "dmarc": "pass"
                  },
                  "raw": {
                    "download_url": "https://zapsmtp.xyz/v1/files/eyJ0Ijoi....Qm9n",
                    "expires_at": "2026-10-21T16:12:00Z"
                  },
                  "attachments": [
                    {
                      "object": "attachment",
                      "id": "5b0f8f7e-2a1c-5d3e-9f4a-6b7c8d9e0f1a",
                      "filename": "screenshot.png",
                      "content_type": "image/png",
                      "content_disposition": "attachment",
                      "content_id": null,
                      "size": 48213
                    }
                  ],
                  "from_name": "Jane Doe",
                  "reply_text": "Thanks, that fixed it!",
                  "mailbox_hash": "1234",
                  "in_reply_to_email_id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23",
                  "thread_id": "3f1c9a52-6b0e-5d4f-8a71-2c9e0b4d6f13",
                  "automated": null,
                  "envelope": {
                    "from": "jane@example.org",
                    "to": "support+1234@acme.com"
                  },
                  "spam": {
                    "score": 1.2,
                    "is_spam": false,
                    "action": "no action"
                  },
                  "arc": "unknown",
                  "route_id": "019a1f31-0b2c-7d3e-8f4a-5b6c7d8e9f01",
                  "action": "webhook",
                  "status": "received",
                  "size": 61877,
                  "peer_ip": "198.51.100.7",
                  "helo": "mail.example.org"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: unknown/non-UUID id or past plan retention",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "inbound_not_configured: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-received",
        "summary": "Delete a received email",
        "description": "Permanently erase a received email's content and metadata (GDPR erasure). Requires a full-access live key; test keys get 403 test_key_restricted. Idempotent: deleting an id that does not exist (but is a valid UUID) still returns 200 deleted:true.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "emails.receiving.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Received email id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                },
                "example": {
                  "object": "email",
                  "id": "019a1f30-1d4e-7a6b-8c2d-3e4f5a6b7c8d",
                  "deleted": true
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: id is not a UUID",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "not_ready: this email is still being stored; retry the erasure in a few seconds (Retry-After: 5)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "inbound_not_configured: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/receiving/{id}/attachments": {
      "get": {
        "operationId": "list-received-attachments",
        "summary": "List attachments",
        "description": "List a received email's attachments with signed download links. Requires a full-access key. Each download_url works for one hour without an API key. Files are always served as downloads; HTML, SVG, XML and JavaScript are served as binary so they can never run in a browser.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "emails.receiving.attachments.list",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Received email id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-100; when omitted or out of range all attachments are returned.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Attachment id; returns attachments after it (ignored if unknown).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Attachment id; returns attachments before it (used only when after is absent).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Attachment"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "object": "attachment",
                      "id": "5b0f8f7e-2a1c-5d3e-9f4a-6b7c8d9e0f1a",
                      "filename": "screenshot.png",
                      "content_type": "image/png",
                      "content_disposition": "attachment",
                      "content_id": null,
                      "size": 48213,
                      "download_url": "https://zapsmtp.xyz/v1/files/eyJ0Ijoi....aGk",
                      "expires_at": "2026-10-21T16:12:00Z"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: email not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "inbound_not_configured: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/receiving/{id}/attachments/{aid}": {
      "get": {
        "operationId": "get-received-attachment",
        "summary": "Retrieve an attachment",
        "description": "Retrieve one attachment's metadata and signed download link. Requires a full-access key.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "emails.receiving.attachments.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Received email id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "aid",
            "in": "path",
            "required": true,
            "description": "Attachment id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Attachment"
                },
                "example": {
                  "object": "attachment",
                  "id": "5b0f8f7e-2a1c-5d3e-9f4a-6b7c8d9e0f1a",
                  "filename": "screenshot.png",
                  "content_type": "image/png",
                  "content_disposition": "attachment",
                  "content_id": null,
                  "size": 48213,
                  "download_url": "https://zapsmtp.xyz/v1/files/eyJ0Ijoi....aGk",
                  "expires_at": "2026-10-21T16:12:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: email not found | attachment not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "inbound_not_configured: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/receiving/{id}/redeliver": {
      "post": {
        "operationId": "redeliver-received",
        "summary": "Redeliver to webhooks",
        "description": "Re-send the email.received webhook for a stored message. Requires a full-access live key; test keys get 403 test_key_restricted. The event is re-queued asynchronously (hence 202).",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "emails.receiving.redeliver",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Received email id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceivedEmailAction"
                },
                "example": {
                  "object": "email",
                  "id": "019a1f30-1d4e-7a6b-8c2d-3e4f5a6b7c8d",
                  "redelivered": true
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: email not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "inbound_not_configured: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/receiving/{id}/spam": {
      "post": {
        "operationId": "report-received-spam",
        "summary": "Report spam / not spam",
        "description": "Report a received email as spam or not spam: your account's spam filter learns from it. Requires a full-access live key; test keys get 403 test_key_restricted. Each account has its own statistics: your reports never change another account's filter. The filter starts scoring once it has learned 20 emails of each kind. Reporting the same email twice is harmless. learned is false when the email has too few words to learn from.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "emails.receiving.reportSpam",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Received email id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceivedEmailAction"
                },
                "example": {
                  "object": "email",
                  "id": "01a17204-bd5b-7691-9fca-52161a26e6d7",
                  "spam": true,
                  "learned": true
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown email or past your plan's retention.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "service_unavailable: The spam filter could not learn right now; retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "spam": {
                    "type": "boolean",
                    "description": "true: mail like this is spam; false: it is wanted. Limits: missing → 422 missing_required_field"
                  }
                },
                "required": [
                  "spam"
                ]
              },
              "example": {
                "spam": true
              }
            }
          }
        }
      }
    },
    "/emails/receiving/{id}/reply": {
      "post": {
        "operationId": "reply-received",
        "summary": "Reply to a received email",
        "description": "Reply to a received email: recipients, subject, sender and threading headers default to the email's, so the answer lands in the sender's conversation. Requires a full-access key. Live keys: the From domain must be verified for sending. Our Message-ID of the reply names its thread, so the customer's answer joins the conversation even from a mail client that keeps only In-Reply-To. Every other rule of POST /emails applies: suppressions, quotas, tracking, test keys. Loop protection: replies to automated email need allow_automated, and one conversation takes at most 20 replies an hour.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "emails.receiving.reply",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Received email id",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "optional, 1-256 bytes (see Idempotency)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendEmailResponse"
                },
                "example": {
                  "id": "019a1f41-8b2c-7e3d-9f40-5a6b7c8d9e0f",
                  "thread_id": "3f1c9a52-6b0e-5d4f-8a71-2c9e0b4d6f13"
                }
              }
            }
          },
          "400": {
            "description": "validation_error: invalid JSON / unknown field\ninvalid_idempotency_key: Idempotency-Key must be 1 to 256 bytes",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "domain_not_verified: sender domain is not verified for this account\nrestricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: email not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "idempotency_key_reused: \nidempotency_request_in_progress: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "missing_required_field: from (managed receiving address), to (no sender on the email), or the body\nautomated_message: the email is a bounce, out-of-office, auto-reply or notification; pass allow_automated: true",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limit_exceeded: \nthread_reply_limit: too many replies in this conversation in the last hour (a mail loop?); at most 20 per hour; Retry-After: 3600",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "inbound_not_configured: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "description": "Plain-text body. Either text or html (or a template) is required."
                  },
                  "html": {
                    "type": "string",
                    "description": "HTML body."
                  },
                  "from": {
                    "type": "string",
                    "description": "Default: the address that received the email (e.g. support@acme.com), which must be on a verified sending domain. Required when the email came to a managed *.in.zapsmtp.xyz address (those only receive): 422 missing_required_field."
                  },
                  "to": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ],
                    "description": "Default: the email's Reply-To, else its From. Limits: 422 missing_required_field when the email has neither."
                  },
                  "reply_all": {
                    "type": "boolean",
                    "description": "Also copy everyone on the email's To and Cc, except the receiving address, the sender you reply from and anyone already addressed."
                  },
                  "allow_automated": {
                    "type": "boolean",
                    "description": "Answer an automated email anyway (see automated on the received email). Without it a reply to a bounce, out-of-office, auto-reply or notification is refused with 422 automated_message: two auto-responders answering each other is a mail loop. Bulk mail can be answered without it."
                  },
                  "auto_reply": {
                    "type": "boolean",
                    "description": "This answer is itself automatic (an acknowledgement, a ticket receipt): adds Auto-Submitted: auto-replied and X-Auto-Response-Suppress: All (RFC 3834), so other auto-responders do not answer it."
                  },
                  "cc": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ],
                    "description": "Added to the Cc (reply_all adds the email's recipients after these)."
                  },
                  "bcc": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ],
                    "description": "Bcc recipients."
                  },
                  "reply_to": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    ],
                    "description": "Default: the receiving address when you reply from another one, so the customer's answer comes back to the same inbox."
                  },
                  "subject": {
                    "type": "string",
                    "description": "Default: Re: + the email's subject (kept as is when it already starts with Re:)."
                  },
                  "headers": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Custom headers. In-Reply-To and References are set for you (RFC 5322 threading); a value you give wins."
                  },
                  "attachments": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/OutgoingAttachment"
                    },
                    "description": "Attachments; 40 MB total. Limits: 422 invalid_attachment with message attachments[i]: set either content or path, not both | content must be base64 | content or path is required | filename is required | path must be an http(s) URL | fetching path returned HTTP <n> | attachments exceed 40MB in total"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/Tag"
                    },
                    "description": "Returned in webhooks as data.tags. Limits: at most 20 tags per email; name and value must match ^[A-Za-z0-9_-]{1,256}$ (422 invalid_parameter)"
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Returned in webhooks and GET /emails; filter with GET /emails?metadata[key]=value. Limits: max 10 keys; keys ^[A-Za-z0-9_-]{1,40}$; values max 500 bytes (UTF-8) (422 invalid_parameter)"
                  },
                  "stream": {
                    "type": "string",
                    "enum": [
                      "transactional",
                      "broadcast"
                    ],
                    "description": "Limits: other values → 422 invalid_parameter; conflicting with the key's stream → 403 restricted_api_key"
                  },
                  "tracking": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/Tracking"
                      }
                    ],
                    "description": "Overrides the From domain's open, click and reply tracking defaults for this email."
                  },
                  "template": {
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/TemplateRef"
                      }
                    ],
                    "description": "Render a stored, published template: id = template id or alias. Request subject/from override the template's. Cannot be combined with html/text. Limits: missing id → 422 missing_required_field \"template.id is required\"; unknown → 422 invalid_parameter \"template <id> not found\"; never published → 422 invalid_parameter; variables.global → 422 invalid_parameter (reserved); a value of the wrong type → 422 template_variables_invalid; a required variable without value or default → 422 template_variables_missing; anything else the template uses still absent → 422 template_render_error \"missing template variables: a, b\""
                  },
                  "scheduled_at": {
                    "type": "string",
                    "description": "RFC 3339 time (e.g. 2026-10-21T15:00:00Z) or relative \"in <n> <unit>\" with unit min|mins|minute|minutes|h|hour|hours|d|day|days. Times in the past send immediately. Limits: unparsable → 422 invalid_parameter; more than 7 days ahead → 422 invalid_parameter \"scheduled_at must be within 7 days\""
                  }
                }
              },
              "example": {
                "text": "Thanks, it ships today."
              }
            }
          }
        }
      }
    },
    "/threads": {
      "get": {
        "operationId": "list-threads",
        "summary": "List conversations",
        "description": "List conversations (threads with at least one received email), the most recently active first: a helpdesk inbox. Requires a full-access key. Served from a per-conversation summary kept up to date as emails arrive: a page costs the same however much email you have. A conversation you started (your first email) is counted once the customer answers it.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "threads.list",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-100; out-of-range falls back to 20.",
            "schema": {
              "type": "integer",
              "default": "20"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Cursor: the last_message_at of the last conversation you have (RFC 3339). Limits: 422 invalid_parameter otherwise.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before_id",
            "in": "query",
            "required": false,
            "description": "With before: the id of the last conversation you have, so conversations active at the same instant are neither skipped nor repeated.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "awaiting_reply",
            "in": "query",
            "required": false,
            "description": "true: only conversations whose last human email came in.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "unread",
            "in": "query",
            "required": false,
            "description": "true: only conversations with an email received after their read mark.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "participant",
            "in": "query",
            "required": false,
            "description": "Only conversations this address took part in (case-insensitive).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Thread"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "object": "thread",
                      "id": "3f1c9a52-6b0e-5d4f-8a71-2c9e0b4d6f13",
                      "subject": "Where is my order?",
                      "participants": [
                        "jane@example.org",
                        "support@acme.com"
                      ],
                      "message_count": 3,
                      "inbound_count": 2,
                      "outbound_count": 1,
                      "has_attachments": false,
                      "first_message_at": "2026-10-21T15:10:02.904Z",
                      "last_message_at": "2026-10-21T16:02:13.540Z",
                      "last_inbound_at": "2026-10-21T16:02:13.540Z",
                      "last_message": {
                        "id": "019a1f52-0c1d-7f2e-8a3b-4c5d6e7f8091",
                        "direction": "inbound",
                        "from": "jane@example.org",
                        "subject": "Re: Where is my order?"
                      },
                      "awaiting_reply": true,
                      "unread": true,
                      "read_at": null,
                      "metadata": {
                        "ticket": "T-1042"
                      }
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: before must be an RFC 3339 time",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/threads/{id}": {
      "get": {
        "operationId": "get-thread",
        "summary": "Retrieve a conversation",
        "description": "A conversation: its state (participants, counts, last message, awaiting_reply, unread, metadata) and its received and sent emails, oldest first. Requires a full-access key. awaiting_reply: the last email a person wrote came in (automated mail does not count). unread: something was received after read_at (set with PATCH /threads/{id}). Threads are derived from the standard In-Reply-To / References headers: no setup. Every received email, webhook email.received and send response carries its thread_id. Refused messages are not part of a thread. At most 500 emails are listed (has_more); fetch bodies with GET /emails/receiving/{id} and GET /emails/{id}/content. Emails received before 2026-10-23 have a thread id but are not listed here.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "threads.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Thread id (thread_id of any email in it)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Thread"
                },
                "example": {
                  "object": "thread",
                  "id": "3f1c9a52-6b0e-5d4f-8a71-2c9e0b4d6f13",
                  "subject": "Where is my order?",
                  "participants": [
                    "jane@example.org",
                    "support@acme.com"
                  ],
                  "message_count": 3,
                  "inbound_count": 2,
                  "outbound_count": 1,
                  "has_attachments": false,
                  "first_message_at": "2026-10-21T15:10:02.904Z",
                  "last_message_at": "2026-10-21T16:02:13.540Z",
                  "last_inbound_at": "2026-10-21T16:02:13.540Z",
                  "last_message": {
                    "id": "019a1f52-0c1d-7f2e-8a3b-4c5d6e7f8091",
                    "direction": "inbound",
                    "from": "jane@example.org",
                    "subject": "Re: Where is my order?"
                  },
                  "awaiting_reply": true,
                  "unread": true,
                  "read_at": null,
                  "metadata": {
                    "ticket": "T-1042"
                  },
                  "has_more": false,
                  "data": [
                    {
                      "object": "email",
                      "direction": "inbound",
                      "id": "019a1f30-1d4e-7a6b-8c2d-3e4f5a6b7c8d",
                      "created_at": "2026-10-21T15:10:02.904Z",
                      "from": "jane@example.org",
                      "to": [
                        "support@acme.com"
                      ],
                      "cc": [],
                      "subject": "Where is my order?",
                      "message_id": "<CAF=abc123@mail.example.org>"
                    },
                    {
                      "object": "email",
                      "direction": "outbound",
                      "id": "019a1f41-8b2c-7e3d-9f40-5a6b7c8d9e0f",
                      "created_at": "2026-10-21T15:20:41.112Z",
                      "from": "Acme Support <support@acme.com>",
                      "to": [
                        "jane@example.org"
                      ],
                      "cc": [],
                      "subject": "Re: Where is my order?"
                    },
                    {
                      "object": "email",
                      "direction": "inbound",
                      "id": "019a1f52-0c1d-7f2e-8a3b-4c5d6e7f8091",
                      "created_at": "2026-10-21T16:02:13.540Z",
                      "from": "jane@example.org",
                      "to": [
                        "support@acme.com"
                      ],
                      "cc": [],
                      "subject": "Automatic reply: Where is my order?",
                      "message_id": "<CAF=def456@mail.example.org>",
                      "automated": "out_of_office"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: thread not found (or past your plan's log retention)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "update-thread",
        "summary": "Mark read, set metadata",
        "description": "Mark a conversation read or unread and set its metadata. Requires a full-access live key; test keys get 403 test_key_restricted. Omitted fields are kept.",
        "tags": [
          "Received emails"
        ],
        "x-sdk-method": "threads.update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Thread id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Thread"
                },
                "example": {
                  "object": "thread",
                  "id": "3f1c9a52-6b0e-5d4f-8a71-2c9e0b4d6f13",
                  "subject": "Where is my order?",
                  "participants": [
                    "jane@example.org",
                    "support@acme.com"
                  ],
                  "message_count": 3,
                  "inbound_count": 2,
                  "outbound_count": 1,
                  "has_attachments": false,
                  "first_message_at": "2026-10-21T15:10:02.904Z",
                  "last_message_at": "2026-10-21T16:02:13.540Z",
                  "last_inbound_at": "2026-10-21T16:02:13.540Z",
                  "last_message": {
                    "id": "019a1f52-0c1d-7f2e-8a3b-4c5d6e7f8091",
                    "direction": "inbound",
                    "from": "jane@example.org",
                    "subject": "Re: Where is my order?"
                  },
                  "awaiting_reply": true,
                  "unread": false,
                  "read_at": "2026-10-21T16:05:00.000Z",
                  "metadata": {
                    "ticket": "T-1042"
                  }
                }
              }
            }
          },
          "400": {
            "description": "validation_error: invalid JSON / unknown field",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: thread not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: metadata limits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "read": {
                    "type": "boolean",
                    "description": "true sets read_at to now (unread again once a new email arrives); false clears it."
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "Your own key-value pairs (a ticket id, a CRM deal), replacing the previous ones. Limits: at most 20 keys matching [A-Za-z0-9_-]{1,40}, values up to 500 bytes (UTF-8) (422 invalid_parameter)."
                  }
                }
              },
              "example": {
                "read": true,
                "metadata": {
                  "ticket": "T-1042"
                }
              }
            }
          }
        }
      }
    },
    "/inbound/domains": {
      "get": {
        "operationId": "list-inbound-domains",
        "summary": "List inbound domains",
        "description": "List inbound domains (oldest first). Requires a full-access key. MX target host comes from config (ZAP_INBOUND_HOST, defaults to the API hostname); managed zone from ZAP_INBOUND_ZONE.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.domains.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/InboundDomain"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "019a1f20-4c5d-7e6f-8a9b-0c1d2e3f4a5b",
                      "name": "k3f9x2m7q1.in.zapsmtp.xyz",
                      "managed": true,
                      "reject_spam": false,
                      "mx_verified": true,
                      "last_checked_at": "2026-10-20T10:00:00Z",
                      "created_at": "2026-10-20T10:00:00Z",
                      "records": [],
                      "example_address": "anything@k3f9x2m7q1.in.zapsmtp.xyz"
                    },
                    {
                      "id": "019a1f21-5d6e-7f80-9a1b-2c3d4e5f6a7b",
                      "name": "reply.acme.com",
                      "managed": false,
                      "reject_spam": true,
                      "mx_verified": false,
                      "last_checked_at": null,
                      "created_at": "2026-10-20T11:30:00Z",
                      "records": [
                        {
                          "record": "MX",
                          "type": "MX",
                          "name": "reply.acme.com",
                          "value": "10 zapsmtp.xyz",
                          "required": true,
                          "status": "pending"
                        }
                      ],
                      "example_address": "anything@reply.acme.com"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-inbound-domain",
        "summary": "Add an inbound domain",
        "description": "Create an inbound domain: a managed address (<slug>.<inbound zone>) or your own domain. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.domains.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboundDomain"
                },
                "example": {
                  "id": "019a1f20-4c5d-7e6f-8a9b-0c1d2e3f4a5b",
                  "name": "k3f9x2m7q1.in.zapsmtp.xyz",
                  "managed": true,
                  "reject_spam": false,
                  "mx_verified": true,
                  "last_checked_at": "2026-10-21T15:00:00Z",
                  "created_at": "2026-10-21T15:00:00Z",
                  "records": [],
                  "example_address": "anything@k3f9x2m7q1.in.zapsmtp.xyz"
                }
              }
            }
          },
          "403": {
            "description": "domain_not_verified: verify <name> (or its parent domain) for sending first; inbound reuses that proof of ownership\nrestricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict: this domain already receives mail on ZapSMTP",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: invalid domain name\nreserved_domain: this domain is reserved by ZapSMTP; use a managed address or your own domain",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "inbound_not_configured: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "managed": {
                    "type": "boolean",
                    "description": "true: create an instant managed domain <10 random lowercase chars>.<inbound zone>; no DNS needed; name is ignored."
                  },
                  "name": {
                    "type": "string",
                    "description": "Required unless managed is true. Your own domain. It (or a parent) must be verified for sending by the account. Then publish MX 10 <inbound host> and call verify. Limits: invalid → 422 invalid_parameter \"invalid domain name\"; ZapSMTP-owned names → 422 reserved_domain; not verified for sending → 403 domain_not_verified"
                  },
                  "reject_spam": {
                    "type": "boolean",
                    "description": "Refuse messages flagged as spam at SMTP time instead of delivering them with is_spam: true."
                  },
                  "require_tls": {
                    "type": "boolean",
                    "description": "Accept encrypted mail only: senders without STARTTLS are refused with 530 5.7.0."
                  }
                }
              },
              "example": {
                "managed": true
              }
            }
          }
        }
      }
    },
    "/inbound/domains/{id}": {
      "get": {
        "operationId": "get-inbound-domain",
        "summary": "Retrieve an inbound domain",
        "description": "Retrieve an inbound domain. Requires a full-access key.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.domains.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Inbound domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboundDomain"
                },
                "example": {
                  "id": "019a1f21-5d6e-7f80-9a1b-2c3d4e5f6a7b",
                  "name": "reply.acme.com",
                  "managed": false,
                  "reject_spam": true,
                  "mx_verified": true,
                  "last_checked_at": "2026-10-21T15:05:00Z",
                  "created_at": "2026-10-20T11:30:00Z",
                  "records": [
                    {
                      "record": "MX",
                      "type": "MX",
                      "name": "reply.acme.com",
                      "value": "10 zapsmtp.xyz",
                      "required": true,
                      "status": "verified"
                    }
                  ],
                  "example_address": "anything@reply.acme.com"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: inbound domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "update-inbound-domain",
        "summary": "Update an inbound domain",
        "description": "Update an inbound domain's spam policy. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.domains.update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Inbound domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboundDomain"
                },
                "example": {
                  "id": "019a1f21-5d6e-7f80-9a1b-2c3d4e5f6a7b",
                  "name": "reply.acme.com",
                  "managed": false,
                  "reject_spam": true,
                  "mx_verified": true,
                  "last_checked_at": "2026-10-21T15:05:00Z",
                  "created_at": "2026-10-20T11:30:00Z",
                  "records": [
                    {
                      "record": "MX",
                      "type": "MX",
                      "name": "reply.acme.com",
                      "value": "10 zapsmtp.xyz",
                      "required": true,
                      "status": "verified"
                    }
                  ],
                  "example_address": "anything@reply.acme.com"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: inbound domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reject_spam": {
                    "type": "boolean",
                    "description": "Refuse flagged spam (550) instead of delivering it with is_spam: true."
                  },
                  "require_tls": {
                    "type": "boolean",
                    "description": "Accept encrypted mail only: senders without STARTTLS are refused with 530 5.7.0."
                  }
                }
              },
              "example": {
                "reject_spam": true
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-inbound-domain",
        "summary": "Delete an inbound domain",
        "description": "Delete an inbound domain. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.domains.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Inbound domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: inbound domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/inbound/domains/{id}/verify": {
      "post": {
        "operationId": "verify-inbound-domain",
        "summary": "Verify MX records",
        "description": "Check the domain's MX record now. Requires a full-access live key; test keys get 403 test_key_restricted. mx_verified becomes true as soon as any MX record of the domain points to our inbound host.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.domains.verify",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Inbound domain id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboundDomainCheck"
                },
                "example": {
                  "domain": {
                    "id": "019a1f21-5d6e-7f80-9a1b-2c3d4e5f6a7b",
                    "name": "reply.acme.com",
                    "managed": false,
                    "reject_spam": true,
                    "mx_verified": true,
                    "last_checked_at": "2026-10-21T15:05:00Z",
                    "created_at": "2026-10-20T11:30:00Z",
                    "records": [
                      {
                        "record": "MX",
                        "type": "MX",
                        "name": "reply.acme.com",
                        "value": "10 zapsmtp.xyz",
                        "required": true,
                        "status": "verified"
                      }
                    ],
                    "example_address": "anything@reply.acme.com"
                  },
                  "mx_found": [
                    "zapsmtp.xyz"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: inbound domain not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/inbound/routes": {
      "get": {
        "operationId": "list-routes",
        "summary": "List routes",
        "description": "List inbound routes in evaluation order (priority ascending, then created_at). Requires a full-access key.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.routes.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/InboundRoute"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "019a1f31-0b2c-7d3e-8f4a-5b6c7d8e9f01",
                      "name": "Support tickets",
                      "priority": 10,
                      "match_recipient": "support+*@acme.com",
                      "match_sender": "",
                      "match_header": "",
                      "match_header_value": "",
                      "action": "webhook",
                      "webhook_id": "019a1f22-6e7f-7091-8a2b-3c4d5e6f7a8b",
                      "enabled": true,
                      "created_at": "2026-10-20T12:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-route",
        "summary": "Create a route",
        "description": "Create an inbound route (max 100 per account). Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.routes.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboundRoute"
                },
                "example": {
                  "id": "019a1f31-0b2c-7d3e-8f4a-5b6c7d8e9f01",
                  "name": "Support tickets",
                  "priority": 10,
                  "match_recipient": "support+*@acme.com",
                  "match_sender": "",
                  "match_header": "",
                  "match_header_value": "",
                  "action": "webhook",
                  "webhook_id": "019a1f22-6e7f-7091-8a2b-3c4d5e6f7a8b",
                  "enabled": true,
                  "created_at": "2026-10-21T15:20:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: validation failures or \"at most 100 routes per account\"",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Label (trimmed)."
                  },
                  "priority": {
                    "type": "integer",
                    "description": "Lower runs first; first match wins."
                  },
                  "match_recipient": {
                    "type": "string",
                    "description": "Glob (case-insensitive, * and ?) e.g. support+*@acme.com, or /regex/ (RE2, case-insensitive). Empty matches all. Limits: max 512 chars; must compile (422 invalid_parameter)"
                  },
                  "match_sender": {
                    "type": "string",
                    "description": "Same syntax, matched against the envelope sender. Limits: max 512 chars; must compile"
                  },
                  "match_header": {
                    "type": "string",
                    "description": "Header name to test."
                  },
                  "match_header_value": {
                    "type": "string",
                    "description": "Glob or /regex/ for that header's value. Limits: max 512 chars; must compile"
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "webhook",
                      "store",
                      "forward",
                      "reject"
                    ],
                    "description": "webhook: deliver email.received only to webhook_id; store: keep without webhook; forward: keep and forward to forward_id (a confirmed forward destination); reject: refuse with 550 at SMTP time. Limits: 422 invalid_parameter \"action must be webhook, store, reject or forward\""
                  },
                  "webhook_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Required when action is webhook. A webhook of this account. Cleared for store/reject. Limits: 422 \"webhook_id is required for action webhook\" / \"webhook_id does not belong to this account\""
                  },
                  "forward_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "A confirmed forward destination of this account (action forward). Cleared for other actions. Limits: 422 \"forward_id is required for action forward\" / \"forward_id does not belong to this account\" / \"... is not confirmed yet\""
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "action"
                ]
              },
              "example": {
                "name": "Support tickets",
                "priority": 10,
                "match_recipient": "support+*@acme.com",
                "action": "store"
              }
            }
          }
        }
      }
    },
    "/inbound/routes/{id}": {
      "get": {
        "operationId": "get-route",
        "summary": "Retrieve a route",
        "description": "Retrieve an inbound route. Requires a full-access key.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.routes.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Route id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboundRoute"
                },
                "example": {
                  "id": "019a1f31-0b2c-7d3e-8f4a-5b6c7d8e9f01",
                  "name": "Support tickets",
                  "priority": 10,
                  "match_recipient": "support+*@acme.com",
                  "match_sender": "",
                  "match_header": "",
                  "match_header_value": "",
                  "action": "webhook",
                  "webhook_id": "019a1f22-6e7f-7091-8a2b-3c4d5e6f7a8b",
                  "enabled": true,
                  "created_at": "2026-10-20T12:00:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: route not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "update-route",
        "summary": "Update a route",
        "description": "Update an inbound route (partial; same fields and validation as create). Requires a full-access live key; test keys get 403 test_key_restricted. Any subset of the POST /inbound/routes fields. Omitted fields keep their value; webhook_id: \"\" clears it. The resulting route must still be valid (e.g. action webhook needs webhook_id).",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.routes.update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Route id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboundRoute"
                },
                "example": {
                  "id": "019a1f31-0b2c-7d3e-8f4a-5b6c7d8e9f01",
                  "name": "Support tickets",
                  "priority": 5,
                  "match_recipient": "support+*@acme.com",
                  "match_sender": "",
                  "match_header": "",
                  "match_header_value": "",
                  "action": "store",
                  "webhook_id": null,
                  "enabled": true,
                  "created_at": "2026-10-20T12:00:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: route not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Label (trimmed)."
                  },
                  "priority": {
                    "type": "integer",
                    "description": "Lower runs first; first match wins."
                  },
                  "match_recipient": {
                    "type": "string",
                    "description": "Glob (case-insensitive, * and ?) e.g. support+*@acme.com, or /regex/ (RE2, case-insensitive). Empty matches all. Limits: max 512 chars; must compile (422 invalid_parameter)"
                  },
                  "match_sender": {
                    "type": "string",
                    "description": "Same syntax, matched against the envelope sender. Limits: max 512 chars; must compile"
                  },
                  "match_header": {
                    "type": "string",
                    "description": "Header name to test."
                  },
                  "match_header_value": {
                    "type": "string",
                    "description": "Glob or /regex/ for that header's value. Limits: max 512 chars; must compile"
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "webhook",
                      "store",
                      "forward",
                      "reject"
                    ],
                    "description": "webhook: deliver email.received only to webhook_id; store: keep without webhook; forward: keep and forward to forward_id (a confirmed forward destination); reject: refuse with 550 at SMTP time. Limits: 422 invalid_parameter \"action must be webhook, store, reject or forward\""
                  },
                  "webhook_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "A webhook of this account. Cleared for store/reject. Limits: 422 \"webhook_id is required for action webhook\" / \"webhook_id does not belong to this account\""
                  },
                  "forward_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "A confirmed forward destination of this account (action forward). Cleared for other actions. Limits: 422 \"forward_id is required for action forward\" / \"forward_id does not belong to this account\" / \"... is not confirmed yet\""
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "enabled": false
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-route",
        "summary": "Delete a route",
        "description": "Delete an inbound route. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.routes.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Route id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: route not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/inbound/forward-destinations": {
      "get": {
        "operationId": "list-forward-destinations",
        "summary": "List forward destinations",
        "description": "List the addresses received mail can be forwarded to. Requires a full-access key.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.forwardDestinations.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ForwardDestination"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "0199f0b2-0000-7000-8000-00000000f001",
                      "email": "team@acme.com",
                      "confirmation_sent_at": "2026-10-25T10:00:00Z",
                      "verified_at": null,
                      "created_at": "2026-10-25T10:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-forward-destination",
        "summary": "Add a forward destination",
        "description": "Add a forward destination: we email it a confirmation link; routes can forward there once its owner confirms. Requires a full-access live key; test keys get 403 test_key_restricted. The confirmation page asks for a click, so mail scanners that follow links cannot confirm. Forwarded mail keeps its original From and DKIM, is ARC-signed by us, counts as one sent email and appears in the email log; spam is never forwarded.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.forwardDestinations.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForwardDestination"
                },
                "example": {
                  "id": "0199f0b2-0000-7000-8000-00000000f001",
                  "email": "team@acme.com",
                  "confirmation_sent_at": "2026-10-25T10:00:00Z",
                  "verified_at": null,
                  "created_at": "2026-10-25T10:00:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict: <email> is already a forward destination",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: \"email must be a plain address (name@example.com)\" | \"cannot forward to a ZapSMTP receiving address (it would loop)\"\nlimit_exceeded: at most 20 forward destinations per account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limit_exceeded: at most 20 forward destinations can be added a day",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "service_unavailable: the destination was added but its confirmation email could not be sent; resend it",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "A plain address. Not a ZapSMTP receiving address (it would loop)."
                  }
                },
                "required": [
                  "email"
                ]
              },
              "example": {
                "email": "team@acme.com"
              }
            }
          }
        }
      }
    },
    "/inbound/forward-destinations/{id}/resend": {
      "post": {
        "operationId": "resend-forward-confirmation",
        "summary": "Resend the confirmation",
        "description": "Email a new confirmation link (the previous one stops working). Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.forwardDestinations.resendConfirmation",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Forward destination id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForwardDestination"
                },
                "example": {
                  "id": "0199f0b2-0000-7000-8000-00000000f001",
                  "email": "team@acme.com",
                  "confirmation_sent_at": "2026-10-25T10:00:00Z",
                  "verified_at": null,
                  "created_at": "2026-10-25T10:00:00Z"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: no unconfirmed forward destination with this id",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limit_exceeded: a confirmation email was sent less than a minute ago",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "service_unavailable: the confirmation email could not be sent; try again",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/inbound/forward-destinations/{id}": {
      "delete": {
        "operationId": "delete-forward-destination",
        "summary": "Remove a forward destination",
        "description": "Remove a forward destination; routes forwarding there only store from then on. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.forwardDestinations.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Forward destination id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Deleted"
                },
                "example": {
                  "object": "forward_destination",
                  "id": "0199f0b2-0000-7000-8000-00000000f001",
                  "deleted": true
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: forward destination not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/inbound/stats": {
      "get": {
        "operationId": "inbound-stats",
        "summary": "Inbound stats",
        "description": "Inbound counters for the last 24 hours. Requires a full-access key.",
        "tags": [
          "Inbound setup"
        ],
        "x-sdk-method": "inbound.getStats",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InboundStats"
                },
                "example": {
                  "received": 128,
                  "rejected": 3,
                  "spam": 7
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "inbound_not_configured: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/suppressions": {
      "get": {
        "operationId": "list-suppressions",
        "summary": "List suppressions",
        "description": "List suppressed addresses, newest first, with cursor pagination. Requires a full-access key. reason is hard_bounce, complaint, unsubscribe or manual; source_id is the email that caused it (null when added by hand). Pass next_cursor as after for the next page. unsubscribe stops only broadcast email (stream: broadcast); transactional email to the address still goes out. Every other reason stops all email to it.",
        "tags": [
          "Suppressions"
        ],
        "x-sdk-method": "suppressions.list",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1-1000; out-of-range falls back to 100.",
            "schema": {
              "type": "integer",
              "default": "100"
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from next_cursor. Limits: 422 invalid_parameter \"invalid after cursor\"",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "Legacy: RFC 3339 timestamp; returns entries created before it. Ignored when after is set. Limits: 422 invalid_parameter \"before must be RFC3339\"",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Suppression"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": true,
                  "data": [
                    {
                      "email": "old@example.org",
                      "reason": "hard_bounce",
                      "source_id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23",
                      "created_at": "2026-10-21T15:04:13Z"
                    },
                    {
                      "email": "angry@example.net",
                      "reason": "complaint",
                      "source_id": "019a1f2a-1b2c-7d3e-8f4a-5b6c7d8e9f00",
                      "created_at": "2026-10-21T11:20:40Z"
                    }
                  ],
                  "next_cursor": "MTc2MTA0NzI0MDAwMDAwMDAwMHxhbmdyeUBleGFtcGxlLm5ldA"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "add-suppression",
        "summary": "Add a suppression",
        "description": "Add an address to the suppression list. Requires a full-access live key; test keys get 403 test_key_restricted. Idempotent: an existing entry keeps its reason, except that an unsubscribe entry becomes manual when you add it as manual (a later bounce or complaint upgrades it the same way). The response echoes the requested reason with 201.",
        "tags": [
          "Suppressions"
        ],
        "x-sdk-method": "suppressions.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Suppression"
                },
                "example": {
                  "email": "someone@example.org",
                  "reason": "manual"
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "description": "Address (stored lowercased). Limits: 422 invalid_parameter \"invalid email\""
                  },
                  "reason": {
                    "type": "string",
                    "enum": [
                      "manual",
                      "unsubscribe"
                    ],
                    "description": "manual: no email at all; unsubscribe: no broadcast email (transactional email still goes out). Limits: 422 invalid_parameter \"reason must be manual or unsubscribe\""
                  }
                },
                "required": [
                  "email"
                ]
              },
              "example": {
                "email": "former-customer@example.com",
                "reason": "manual"
              }
            }
          }
        }
      }
    },
    "/suppressions/{email}": {
      "get": {
        "operationId": "get-suppression",
        "summary": "Retrieve a suppression",
        "description": "Check whether one address is suppressed, and why. Requires a full-access key. unsubscribe stops only broadcast email (stream: broadcast); transactional email to the address still goes out. Every other reason stops all email to it.",
        "tags": [
          "Suppressions"
        ],
        "x-sdk-method": "suppressions.get",
        "parameters": [
          {
            "name": "email",
            "in": "path",
            "required": true,
            "description": "The address (case-insensitive, URL-encoded).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Suppression"
                },
                "example": {
                  "email": "former-customer@example.com",
                  "reason": "unsubscribe",
                  "source_id": null,
                  "created_at": "2026-10-20T08:00:00Z"
                }
              }
            }
          },
          "404": {
            "description": "not_found: The address is not suppressed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-suppression",
        "summary": "Remove a suppression",
        "description": "Remove an address from the suppression list. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Suppressions"
        ],
        "x-sdk-method": "suppressions.delete",
        "parameters": [
          {
            "name": "email",
            "in": "path",
            "required": true,
            "description": "Address (URL-encoded; matched case-insensitively)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: suppression not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/suppressions/batch": {
      "post": {
        "operationId": "add-suppressions",
        "summary": "Add suppressions in bulk",
        "description": "Add up to 1,000 addresses in one call. Duplicates are ignored; existing entries keep their reason (an unsubscribe becomes manual when added as manual); sends see the change immediately. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Suppressions"
        ],
        "x-sdk-method": "suppressions.createBatch",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuppressionBatch"
                },
                "example": {
                  "object": "suppression_batch",
                  "added": 2,
                  "reason": "manual",
                  "emails": [
                    "ann@example.com",
                    "bob@example.com"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "test_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: Empty or over 1,000 addresses, an invalid address, or an unknown reason.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "emails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "1–1,000 addresses."
                  },
                  "reason": {
                    "type": "string",
                    "enum": [
                      "manual",
                      "unsubscribe"
                    ],
                    "description": "manual: no email at all; unsubscribe: no broadcast email (transactional email still goes out)."
                  }
                },
                "required": [
                  "emails"
                ]
              },
              "example": {
                "emails": [
                  "ann@example.com",
                  "bob@example.com"
                ],
                "reason": "manual"
              }
            }
          }
        }
      }
    },
    "/suppressions/batch/remove": {
      "post": {
        "operationId": "remove-suppressions",
        "summary": "Remove suppressions in bulk",
        "description": "Remove up to 1,000 addresses in one call. Addresses that are not on the list are ignored. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "Suppressions"
        ],
        "x-sdk-method": "suppressions.deleteBatch",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuppressionBatch"
                },
                "example": {
                  "object": "suppression_batch",
                  "removed": 1,
                  "emails": [
                    "ann@example.com"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "test_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: Empty or over 1,000 addresses, or an invalid address.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "emails": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "1–1,000 addresses."
                  }
                },
                "required": [
                  "emails"
                ]
              },
              "example": {
                "emails": [
                  "ann@example.com",
                  "bob@example.com"
                ]
              }
            }
          }
        }
      }
    },
    "/stats": {
      "get": {
        "operationId": "stats",
        "summary": "Totals",
        "description": "Event counts by status over the last N hours (live traffic only). Requires a full-access key. Counts events (not unique emails), ordered by status name; test-mode traffic excluded.",
        "tags": [
          "Statistics"
        ],
        "x-sdk-method": "stats.get",
        "parameters": [
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "description": "1-720; out-of-range falls back to 24.",
            "schema": {
              "type": "integer",
              "default": "24"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Stats"
                },
                "example": {
                  "hours": 24,
                  "data": [
                    {
                      "status": "bounced",
                      "count": 12
                    },
                    {
                      "status": "delivered",
                      "count": 1840
                    },
                    {
                      "status": "queued",
                      "count": 1861
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/stats/timeseries": {
      "get": {
        "operationId": "stats-timeseries",
        "summary": "Time series",
        "description": "Event counts by status in time buckets. Requires a full-access key. One point per (bucket, status); empty buckets are not emitted. Test-mode traffic excluded.",
        "tags": [
          "Statistics"
        ],
        "x-sdk-method": "stats.timeseries",
        "parameters": [
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "description": "1-720; out-of-range falls back to 24. Bucket size: <=1h → 60 s, <=6h → 300 s, <=24h → 1800 s, <=168h → 10800 s, otherwise 43200 s.",
            "schema": {
              "type": "integer",
              "default": "24"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatsTimeseries"
                },
                "example": {
                  "hours": 24,
                  "bucket_seconds": 1800,
                  "since": "2026-10-20T15:00:00Z",
                  "data": [
                    {
                      "t": "2026-10-20T15:00:00Z",
                      "status": "delivered",
                      "count": 74
                    },
                    {
                      "t": "2026-10-20T15:00:00Z",
                      "status": "queued",
                      "count": 75
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/stats/breakdown": {
      "get": {
        "operationId": "stats-breakdown",
        "summary": "Breakdown",
        "description": "Per-provider delivery, bounce classes, engagement and top clicked links. Requires a full-access key. Providers are Gmail, Microsoft, Yahoo, Apple and Other. delayed counts emails that were delayed at least once.",
        "tags": [
          "Statistics"
        ],
        "x-sdk-method": "stats.breakdown",
        "parameters": [
          {
            "name": "hours",
            "in": "query",
            "required": false,
            "description": "1-720; out-of-range falls back to 24.",
            "schema": {
              "type": "integer",
              "default": "24"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatsBreakdown"
                },
                "example": {
                  "providers": [
                    {
                      "provider": "Gmail",
                      "sent": 920,
                      "delivered": 915,
                      "bounced": 3,
                      "delayed": 4,
                      "complained": 1
                    },
                    {
                      "provider": "Microsoft",
                      "sent": 410,
                      "delivered": 402,
                      "bounced": 6,
                      "delayed": 9,
                      "complained": 0
                    }
                  ],
                  "bounces": [
                    {
                      "classification": "InvalidRecipient",
                      "count": 7
                    }
                  ],
                  "engagement": {
                    "delivered": 1840,
                    "unique_opens": 702,
                    "unique_clicks": 133,
                    "opens": 1190,
                    "clicks": 201,
                    "human_unique_opens": 386,
                    "machine_opens": 595
                  },
                  "top_links": [
                    {
                      "url": "https://acme.com/orders/A-1042",
                      "clicks": 88,
                      "unique": 80
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/metrics": {
      "get": {
        "operationId": "metrics",
        "summary": "Metrics by domain, stream, tag or provider",
        "description": "Delivery and engagement of live mail by sending domain, stream, tag or mailbox provider, with rates and a time series. Requires a full-access key. Counts are recipients, except delayed, opened and clicked: unique emails. Delivery and bounce rates are of sent; complaint, open and click rates of delivered. Test-mode mail is excluded. Kept for 400 days. An out-of-band bounce (a later bounce email from the remote server) has no sending domain: it is grouped under an empty value. Totals and the series count each email once whatever the dimension; with dimension=tag an email with several tags appears in each of its tags' groups.",
        "tags": [
          "Statistics"
        ],
        "x-sdk-method": "stats.metrics",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "RFC 3339 start. At most 400 days before to.",
            "schema": {
              "type": "string",
              "default": "7 days ago"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "RFC 3339 end (exclusive).",
            "schema": {
              "type": "string",
              "default": "now"
            }
          },
          {
            "name": "granularity",
            "in": "query",
            "required": false,
            "description": "hour (ranges up to 31 days) or day for series.",
            "schema": {
              "type": "string",
              "default": "hour up to 48 hours, else day"
            }
          },
          {
            "name": "dimension",
            "in": "query",
            "required": false,
            "description": "domain, stream, tag or provider: adds groups, one row per value, busiest first.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "description": "Only this sending (From) domain.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "stream",
            "in": "query",
            "required": false,
            "description": "transactional or broadcast.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "provider",
            "in": "query",
            "required": false,
            "description": "Gmail, Microsoft, Yahoo, Apple or Other.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "description": "Only emails with this tag, as name=value. Cannot be combined with domain, stream or provider, and groups only by tag.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Metrics"
                },
                "example": {
                  "object": "metrics",
                  "from": "2026-10-18T00:00:00Z",
                  "to": "2026-10-25T00:00:00Z",
                  "granularity": "day",
                  "dimension": "domain",
                  "totals": {
                    "sent": 12400,
                    "delivered": 12210,
                    "bounced": 95,
                    "delayed": 3,
                    "complained": 4,
                    "opened": 4380,
                    "human_opened": 2409,
                    "clicked": 912,
                    "suppressed": 2,
                    "failed": 0,
                    "delivery_rate": 0.9847,
                    "bounce_rate": 0.0077,
                    "complaint_rate": 0.0003,
                    "open_rate": 0.3587,
                    "human_open_rate": 0.1972,
                    "click_rate": 0.0747
                  },
                  "series": [
                    {
                      "time": "2026-10-18T00:00:00Z",
                      "sent": 1700,
                      "delivered": 1676,
                      "bounced": 14,
                      "delayed": 3,
                      "complained": 1,
                      "opened": 601,
                      "human_opened": 331,
                      "clicked": 120,
                      "suppressed": 2,
                      "failed": 0,
                      "delivery_rate": 0.9859,
                      "bounce_rate": 0.0082,
                      "complaint_rate": 0.0006,
                      "open_rate": 0.3586,
                      "human_open_rate": 0.1974,
                      "click_rate": 0.0716
                    }
                  ],
                  "groups": [
                    {
                      "value": "acme.com",
                      "sent": 9800,
                      "delivered": 9668,
                      "bounced": 70,
                      "delayed": 3,
                      "complained": 3,
                      "opened": 3540,
                      "human_opened": 1947,
                      "clicked": 760,
                      "suppressed": 2,
                      "failed": 0,
                      "delivery_rate": 0.9865,
                      "bounce_rate": 0.0071,
                      "complaint_rate": 0.0003,
                      "open_rate": 0.3662,
                      "human_open_rate": 0.2013,
                      "click_rate": 0.0786
                    },
                    {
                      "value": "news.acme.com",
                      "sent": 2600,
                      "delivered": 2542,
                      "bounced": 25,
                      "delayed": 3,
                      "complained": 1,
                      "opened": 840,
                      "human_opened": 462,
                      "clicked": 152,
                      "suppressed": 2,
                      "failed": 0,
                      "delivery_rate": 0.9777,
                      "bounce_rate": 0.0096,
                      "complaint_rate": 0.0004,
                      "open_rate": 0.3304,
                      "human_open_rate": 0.1817,
                      "click_rate": 0.0598
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: Bad time, range, granularity or dimension, or a tag combined with another filter.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api-keys": {
      "get": {
        "operationId": "list-api-keys",
        "summary": "List API keys",
        "description": "List active API keys (newest first); tokens are never returned. Requires a full-access key. Revoked keys and SMTP credentials are not listed. last_used_at is updated at most every 5 minutes.",
        "tags": [
          "API keys & SMTP credentials"
        ],
        "x-sdk-method": "apiKeys.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ApiKey"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "id": "019a1f05-3c4d-7e5f-8a6b-7c8d9e0f1a2b",
                      "name": "Production",
                      "prefix": "zap_8fK2mQ",
                      "permission": "sending_access",
                      "mode": "live",
                      "stream": "transactional",
                      "expires_at": null,
                      "domain_id": "019a1f10-8a10-7b22-8c31-5d2e9f0a4b17",
                      "last_used_at": "2026-10-21T15:04:10Z",
                      "created_at": "2026-10-20T09:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-api-key",
        "summary": "Create an API key",
        "description": "Create an API key; the full key (token) is returned only once. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "API keys & SMTP credentials"
        ],
        "x-sdk-method": "apiKeys.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedApiKey"
                },
                "example": {
                  "id": "019a1f05-3c4d-7e5f-8a6b-7c8d9e0f1a2b",
                  "token": "zap_8fK2mQ9xLr3TzV7bN1cW5yHjP0aS4dE6gU2iO9kX",
                  "key": {
                    "id": "019a1f05-3c4d-7e5f-8a6b-7c8d9e0f1a2b",
                    "name": "Production",
                    "prefix": "zap_8fK2mQ",
                    "permission": "sending_access",
                    "mode": "live",
                    "stream": null,
                    "expires_at": null,
                    "domain_id": "019a1f10-8a10-7b22-8c31-5d2e9f0a4b17",
                    "last_used_at": null,
                    "created_at": "2026-10-21T15:30:00Z"
                  }
                }
              }
            }
          },
          "403": {
            "description": "key_restricted: this API key expires, so the keys it manages must expire no later than it does | this API key is limited to the <stream> stream, and so are the keys it manages\nrestricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: name, permission, domain_id, mode, stream or expiry invalid",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Limits: 1-100 characters (not trimmed) → 422 invalid_parameter \"name is required (max 100 chars)\""
                  },
                  "permission": {
                    "type": "string",
                    "enum": [
                      "full_access",
                      "sending_access"
                    ]
                  },
                  "domain_id": {
                    "type": "string",
                    "description": "Restrict sending to one of the account's domains. Only with sending_access. Limits: 422 \"domain_id can only be used with sending_access\" / \"unknown domain_id\""
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ],
                    "description": "test creates a zap_test_ key (see API keys)."
                  },
                  "stream": {
                    "type": "string",
                    "enum": [
                      "transactional",
                      "broadcast"
                    ],
                    "description": "Restrict the key to one message stream."
                  },
                  "expires_at": {
                    "type": "string",
                    "description": "Limits: must be in the future → 422 \"expires_at must be in the future\""
                  },
                  "expires_in_days": {
                    "type": "integer",
                    "description": "Alternative to expires_at; when > 0 it overrides expires_at."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "checkout-service",
                "permission": "sending_access",
                "mode": "live"
              }
            }
          }
        }
      }
    },
    "/api-keys/{id}": {
      "patch": {
        "operationId": "update-api-key",
        "summary": "Update an API key",
        "description": "Rename a key or change its permission and restrictions. The token and the mode never change; the new rights apply to the next request. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "API keys & SMTP credentials"
        ],
        "x-sdk-method": "apiKeys.update",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "API key id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKey"
                },
                "example": {
                  "id": "019a1c11-2f3e-7a4b-9c5d-6e7f8a9b0c1d",
                  "name": "checkout-service",
                  "prefix": "zap_8fK2mQ",
                  "permission": "sending_access",
                  "mode": "live",
                  "stream": null,
                  "expires_at": null,
                  "domain_id": "019a1e9b-41c2-7a0e-b5d1-3f6c2e8a9d47",
                  "last_used_at": "2026-10-22T09:12:00Z",
                  "created_at": "2026-10-01T10:00:00Z"
                }
              }
            }
          },
          "403": {
            "description": "key_restricted: this API key expires, so the keys it manages must expire no later than it does | this API key is limited to the <stream> stream, and so are the keys it manages\ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown or revoked key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: Invalid name, permission or stream; domain_id with full access; unknown domain; \"domain_id must be a string or null\".",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "1–100 characters."
                  },
                  "permission": {
                    "type": "string",
                    "enum": [
                      "full_access",
                      "sending_access"
                    ]
                  },
                  "domain_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Restrict sending to one verified domain (sending access only). null lifts the restriction."
                  },
                  "stream": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "transactional",
                          "broadcast"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Restrict to one stream. null lifts the restriction."
                  }
                }
              },
              "example": {
                "name": "checkout-service",
                "domain_id": "019a1e9b-41c2-7a0e-b5d1-3f6c2e8a9d47"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "revoke-api-key",
        "summary": "Revoke an API key",
        "description": "Revoke an API key immediately. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "API keys & SMTP credentials"
        ],
        "x-sdk-method": "apiKeys.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "API key id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: api key not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/smtp-credentials": {
      "get": {
        "operationId": "list-smtp-credentials",
        "summary": "List SMTP credentials",
        "description": "List active SMTP credentials plus the plan limit and relay settings. Requires a full-access key. No has_more field on this list. limit = plan's max SMTP credentials (0 = unlimited).",
        "tags": [
          "API keys & SMTP credentials"
        ],
        "x-sdk-method": "smtpCredentials.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmtpCredentialList"
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "019a1f06-4d5e-7f60-8b7c-8d9e0f1a2b3c",
                      "name": "WordPress",
                      "username": "smtp_k3f9x2m7q1ab",
                      "domain_id": null,
                      "last_used_at": "2026-10-21T14:00:00Z",
                      "created_at": "2026-10-20T09:30:00Z"
                    }
                  ],
                  "limit": 10,
                  "settings": {
                    "host": "zapsmtp.xyz",
                    "ports": {
                      "465": "TLS",
                      "587": "STARTTLS",
                      "2525": "STARTTLS"
                    },
                    "mechanisms": [
                      "PLAIN",
                      "LOGIN"
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-smtp-credential",
        "summary": "Create SMTP credentials",
        "description": "Create an SMTP credential; the password is returned only once. Requires a full-access live key; test keys get 403 test_key_restricted. Password: 40 base62 characters. Credentials are sending-only (always behave like sending_access, live mode) and cannot call the HTTP API.",
        "tags": [
          "API keys & SMTP credentials"
        ],
        "x-sdk-method": "smtpCredentials.create",
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SmtpCredential"
                },
                "example": {
                  "id": "019a1f06-4d5e-7f60-8b7c-8d9e0f1a2b3c",
                  "name": "WordPress",
                  "username": "smtp_k3f9x2m7q1ab",
                  "domain_id": null,
                  "created_at": "2026-10-21T15:35:00Z",
                  "password": "Xa7Lq2Vb9Rk4Tm1Wc8Np3Zs6Hd0Fj5Gy2Ue7Io4K",
                  "settings": {
                    "host": "zapsmtp.xyz",
                    "ports": {
                      "465": "TLS",
                      "587": "STARTTLS",
                      "2525": "STARTTLS"
                    },
                    "mechanisms": [
                      "PLAIN",
                      "LOGIN"
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "plan_limit_reached: the <Plan> plan includes <n> SMTP credentials; upgrade your plan to add more\nrestricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Limits: trimmed, 1-100 characters → 422 invalid_parameter \"name is required (max 100 chars)\""
                  },
                  "domain_id": {
                    "type": "string",
                    "description": "Restrict the credential to one of the account's domains. Limits: 422 invalid_parameter \"unknown domain_id\""
                  }
                },
                "required": [
                  "name"
                ]
              },
              "example": {
                "name": "wordpress-shop"
              }
            }
          }
        }
      }
    },
    "/smtp-credentials/{id}": {
      "delete": {
        "operationId": "revoke-smtp-credential",
        "summary": "Revoke SMTP credentials",
        "description": "Revoke an SMTP credential. Requires a full-access live key; test keys get 403 test_key_restricted.",
        "tags": [
          "API keys & SMTP credentials"
        ],
        "x-sdk-method": "smtpCredentials.delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "SMTP credential id",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No content"
          },
          "403": {
            "description": "restricted_api_key: \ntest_key_restricted: test-mode keys can send test email and read, not change the account: use a live key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found: smtp credential not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/logs": {
      "get": {
        "operationId": "list-logs",
        "summary": "List logs",
        "description": "List the API requests made with your keys, newest first. Bodies are on Retrieve a log. Entries appear within seconds and are kept for your plan’s log retention. Requires a full-access key. Requests made with API keys are logged; the dashboard’s own calls are not. The X-Request-Id header of every response is the id of its log entry.",
        "tags": [
          "Logs & usage"
        ],
        "x-sdk-method": "logs.list",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "1–100.",
            "schema": {
              "type": "integer",
              "default": "20"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "description": "A log id: return older entries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "description": "A log id: return newer entries.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "An exact status (422) or a class: 2xx, 4xx, 5xx.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "method",
            "in": "query",
            "required": false,
            "description": "HTTP method.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "path",
            "in": "query",
            "required": false,
            "description": "Path prefix, e.g. /v1/emails.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "api_key_id",
            "in": "query",
            "required": false,
            "description": "Only requests made with this key.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Log"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": true,
                  "data": [
                    {
                      "object": "log",
                      "id": "019a1f31-5b2e-7c9d-8e4f-1a2b3c4d5e6f",
                      "api_key_id": "019a1c11-2f3e-7a4b-9c5d-6e7f8a9b0c1d",
                      "method": "POST",
                      "path": "/v1/emails",
                      "route": "/v1/emails",
                      "status": 200,
                      "duration_ms": 38,
                      "ip": "203.0.113.7",
                      "user_agent": "node-fetch/3.3",
                      "created_at": "2026-10-22T15:04:10.902Z"
                    }
                  ]
                }
              }
            }
          },
          "422": {
            "description": "invalid_parameter: before or after is not a log id.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/logs/{id}": {
      "get": {
        "operationId": "get-log",
        "summary": "Retrieve a log",
        "description": "Retrieve one request with its request and response bodies. Bodies are capped at 16 KB; API keys, passwords and signing secrets are always replaced with [redacted]. Requires a full-access key.",
        "tags": [
          "Logs & usage"
        ],
        "x-sdk-method": "logs.get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Log id (the X-Request-Id of the response).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Log"
                },
                "example": {
                  "object": "log",
                  "id": "019a1f31-5b2e-7c9d-8e4f-1a2b3c4d5e6f",
                  "api_key_id": "019a1c11-2f3e-7a4b-9c5d-6e7f8a9b0c1d",
                  "method": "POST",
                  "path": "/v1/emails",
                  "route": "/v1/emails",
                  "status": 200,
                  "duration_ms": 38,
                  "ip": "203.0.113.7",
                  "user_agent": "node-fetch/3.3",
                  "created_at": "2026-10-22T15:04:10.902Z",
                  "request_body": {
                    "from": "Acme <hello@acme.com>",
                    "to": [
                      "delivered@simulator.zapsmtp.xyz"
                    ],
                    "subject": "Your receipt",
                    "html": "<p>Thanks for your order.</p>"
                  },
                  "response_body": {
                    "id": "019a1f2e-7c3b-7d41-9a52-0c4b8e6f1a23"
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found: Unknown id, or past your plan’s log retention.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/usage": {
      "get": {
        "operationId": "usage",
        "summary": "Retrieve usage",
        "description": "This month’s sending against your plan: emails sent, included volume, limit, overage and, on the Free plan, today’s count. Requires a full-access key. limit is null on paid plans without a spending cap: email keeps flowing and extra volume is billed. The Free plan adds daily_limit and sent_today.",
        "tags": [
          "Logs & usage"
        ],
        "x-sdk-method": "usage.get",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                },
                "example": {
                  "object": "usage",
                  "month": "2026-10",
                  "sent": 52310,
                  "included": 50000,
                  "limit": null,
                  "overage_emails": 2310,
                  "overage_cents": 196,
                  "plan": {
                    "id": "pro_50k",
                    "name": "Pro 50k",
                    "retention_days": 30
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/simulator": {
      "get": {
        "operationId": "simulator",
        "summary": "List simulator addresses",
        "description": "List the simulator addresses and the events each produces. Requires a full-access key.",
        "tags": [
          "Simulator & dedicated IPs"
        ],
        "x-sdk-method": "simulator.get",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Simulator"
                },
                "example": {
                  "domain": "simulator.zapsmtp.xyz",
                  "note": "Simulator recipients never leave ZapSMTP, work with live and test keys, never touch your suppression list or reputation, and accept +labels (delivered+signup@…).",
                  "scenarios": [
                    {
                      "address": "delivered@simulator.zapsmtp.xyz",
                      "event": "email.delivered",
                      "result": "250 accepted by the mailbox"
                    },
                    {
                      "address": "bounced@simulator.zapsmtp.xyz",
                      "event": "email.bounced",
                      "result": "550 5.1.1 Permanent / MailboxDoesNotExist"
                    },
                    {
                      "address": "full@simulator.zapsmtp.xyz",
                      "event": "email.bounced",
                      "result": "552 5.2.2 Permanent / MailboxFull"
                    },
                    {
                      "address": "blocked@simulator.zapsmtp.xyz",
                      "event": "email.bounced",
                      "result": "554 5.7.1 Permanent / SpamBlocked"
                    },
                    {
                      "address": "delayed@simulator.zapsmtp.xyz",
                      "event": "email.delivery_delayed → email.delivered",
                      "result": "451 on the first attempt, delivered ~20 s later"
                    },
                    {
                      "address": "complained@simulator.zapsmtp.xyz",
                      "event": "email.delivered → email.complained",
                      "result": "delivered, then an ARF abuse complaint"
                    },
                    {
                      "address": "suppressed@simulator.zapsmtp.xyz",
                      "event": "email.suppressed",
                      "result": "treated as on your suppression list; not sent"
                    },
                    {
                      "address": "bounce+421+4.7.0+try-later@simulator.zapsmtp.xyz",
                      "event": "email.delivery_delayed",
                      "result": "any reply you need: bounce+<code>[+<x.y.z>][+<words-with-dashes>]"
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/dedicated-ips": {
      "get": {
        "operationId": "dedicated-ips",
        "summary": "List dedicated IPs",
        "description": "List the account's dedicated IPs with warm-up progress and current blocklist listings. Requires a full-access key. status is warming, active or paused. During warm-up, warmup_day and daily_cap show the current day and today’s volume limit. blocklists lists current listings of the IP.",
        "tags": [
          "Simulator & dedicated IPs"
        ],
        "x-sdk-method": "dedicatedIps.list",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/List",
                  "unevaluatedProperties": true,
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DedicatedIp"
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "has_more": false,
                  "data": [
                    {
                      "address": "203.0.113.25",
                      "hostname": "mta25.zapsmtp.com",
                      "status": "warming",
                      "warmup_day": 9,
                      "warmup_days": 30,
                      "warmup_progress": 0.3,
                      "daily_cap": 3000,
                      "blocklists": []
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "restricted_api_key: ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key: zap_… (live) or zap_test_… (test mode)"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Every error carries both shapes: the flat one (statusCode, name, message) and error.",
        "properties": {
          "statusCode": {
            "type": "integer"
          },
          "name": {
            "type": "string",
            "description": "The error code"
          },
          "message": {
            "type": "string"
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "type": {
                "type": "string"
              }
            }
          }
        }
      },
      "List": {
        "type": "object",
        "required": [
          "object",
          "data",
          "has_more"
        ],
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array"
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Pass as after= for the next page (suppressions)."
          }
        }
      },
      "OutgoingAttachment": {
        "type": "object",
        "properties": {
          "filename": {
            "type": "string"
          },
          "content": {
            "type": "string",
            "description": "Base64 of the file. The SDKs' attachment helper fills it from a file or bytes."
          },
          "path": {
            "type": "string",
            "description": "An http(s) URL ZapSMTP downloads the file from."
          },
          "content_type": {
            "type": "string"
          },
          "content_id": {
            "type": "string",
            "description": "Makes the attachment inline: reference it as cid:<content_id>."
          }
        },
        "required": [
          "filename"
        ],
        "description": "A file to attach: content (base64) or path (an http(s) URL ZapSMTP fetches), not both."
      },
      "Tag": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "value"
        ],
        "description": "A name and value returned in webhooks as data.tags."
      },
      "TemplateRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "variables": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "id"
        ],
        "description": "A published template to render: id is its id or alias."
      },
      "Tracking": {
        "type": "object",
        "properties": {
          "opens": {
            "type": "boolean"
          },
          "clicks": {
            "type": "boolean"
          },
          "replies": {
            "type": "boolean"
          }
        },
        "description": "Overrides the From domain's tracking defaults for this email."
      },
      "WebhookFilter": {
        "type": "object",
        "properties": {
          "actions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Narrows email.clicked to some click actions."
      },
      "VariableSpec": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "string",
              "number",
              "boolean",
              "url",
              "date",
              "list",
              "object",
              "any"
            ]
          },
          "required": {
            "type": "boolean"
          },
          "default": {},
          "example": {},
          "description": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "type"
        ],
        "description": "One declared template variable."
      },
      "SendEmailParams": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "RFC 5322 address, e.g. \"Acme <hello@acme.com>\". Domain must be verified (live keys). When only an address is given, the domain's from_name (brand settings) is used as display name. May be omitted when template is used and the template defines from. Limits: missing → 422 missing_required_field; unparsable → 422 invalid_parameter \"invalid from address\""
          },
          "to": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ],
            "description": "Recipient(s). Limits: at least one; each must parse as an address (422 invalid_parameter \"invalid to address ...\")"
          },
          "cc": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ],
            "description": "Cc recipients."
          },
          "bcc": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ],
            "description": "Bcc recipients."
          },
          "reply_to": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ],
            "description": "Reply-To address(es)."
          },
          "subject": {
            "type": "string",
            "description": "Subject line. May be omitted when template is used and the template defines a subject. Limits: blank → 422 missing_required_field"
          },
          "html": {
            "type": "string",
            "description": "HTML body. At least one of html/text is required (unless template is used). Limits: both empty → 422 missing_required_field \"html or text is required\"; cannot be combined with template (422 invalid_parameter)"
          },
          "text": {
            "type": "string",
            "description": "Plain-text body. When only html is given, a plain-text part is generated from it (readable text, links as text (url), hidden elements such as the preheader left out)."
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Custom headers. Limits: Reserved headers are rejected (422 invalid_parameter \"header ... cannot be set\"): From, To, Cc, Bcc, Reply-To, Subject, Date, Message-Id, Mime-Version, Content-Type, Content-Transfer-Encoding, DKIM-Signature, Return-Path, Received, any X-Zap-*, X-ZapRef. Names must be printable ASCII without spaces or ':'."
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OutgoingAttachment"
            },
            "description": "Attachments; 40 MB total. Limits: 422 invalid_attachment with message attachments[i]: set either content or path, not both | content must be base64 | content or path is required | filename is required | path must be an http(s) URL | fetching path returned HTTP <n> | attachments exceed 40MB in total"
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            },
            "description": "Returned in webhooks as data.tags. Limits: at most 20 tags per email; name and value must match ^[A-Za-z0-9_-]{1,256}$ (422 invalid_parameter)"
          },
          "scheduled_at": {
            "type": "string",
            "description": "RFC 3339 time (e.g. 2026-10-21T15:00:00Z) or relative \"in <n> <unit>\" with unit min|mins|minute|minutes|h|hour|hours|d|day|days. Times in the past send immediately. Limits: unparsable → 422 invalid_parameter; more than 7 days ahead → 422 invalid_parameter \"scheduled_at must be within 7 days\""
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Returned in webhooks and GET /emails; filter with GET /emails?metadata[key]=value. Limits: max 10 keys; keys ^[A-Za-z0-9_-]{1,40}$; values max 500 bytes (UTF-8) (422 invalid_parameter)"
          },
          "stream": {
            "type": "string",
            "enum": [
              "transactional",
              "broadcast"
            ],
            "description": "Limits: other values → 422 invalid_parameter; conflicting with the key's stream → 403 restricted_api_key"
          },
          "tracking": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Tracking"
              }
            ],
            "description": "Overrides the From domain's open, click and reply tracking defaults for this email."
          },
          "template": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TemplateRef"
              }
            ],
            "description": "Render a stored, published template: id = template id or alias. Request subject/from override the template's. Cannot be combined with html/text. Limits: missing id → 422 missing_required_field \"template.id is required\"; unknown → 422 invalid_parameter \"template <id> not found\"; never published → 422 invalid_parameter; variables.global → 422 invalid_parameter (reserved); a value of the wrong type → 422 template_variables_invalid; a required variable without value or default → 422 template_variables_missing; anything else the template uses still absent → 422 template_render_error \"missing template variables: a, b\""
          },
          "tls": {
            "type": "string",
            "description": "required or verified: deliver only over TLS (verified: with a valid certificate for the receiving server). Raises the domain's policy, never lowers it."
          }
        },
        "required": [
          "to"
        ],
        "description": "An email to send."
      },
      "Action": {
        "type": "object",
        "properties": {
          "clicks_30d": {
            "type": "integer"
          },
          "clicks_7d": {
            "type": "integer"
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "declared": {
            "type": "boolean"
          },
          "description": {
            "type": "string"
          },
          "last_click_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "name": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "templates": {
            "type": "integer"
          },
          "unique_clickers_30d": {
            "type": "integer"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "webhooks": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "clicks_30d",
          "clicks_7d",
          "created_at",
          "declared",
          "description",
          "last_click_at",
          "name",
          "object",
          "templates",
          "unique_clickers_30d",
          "updated_at",
          "webhooks"
        ]
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "domain_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "id": {
            "type": "string"
          },
          "last_used_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "mode": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "permission": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "stream": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "created_at",
          "domain_id",
          "expires_at",
          "id",
          "last_used_at",
          "mode",
          "name",
          "permission",
          "prefix",
          "stream"
        ]
      },
      "Attachment": {
        "type": "object",
        "properties": {
          "content_disposition": {
            "type": "string"
          },
          "content_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "content_type": {
            "type": "string"
          },
          "download_url": {
            "type": "string"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "filename": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          }
        },
        "required": [
          "content_disposition",
          "content_id",
          "content_type",
          "download_url",
          "expires_at",
          "filename",
          "id",
          "object",
          "size"
        ]
      },
      "Brand": {
        "type": "object",
        "properties": {
          "bimi_record": {
            "$ref": "#/components/schemas/BrandBimiRecord"
          },
          "cert_url": {
            "type": "string"
          },
          "checks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BrandCheck"
            }
          },
          "dmarc": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BrandDmarc"
              },
              {
                "type": "null"
              }
            ]
          },
          "dmarc_record": {
            "$ref": "#/components/schemas/BrandDmarcRecord"
          },
          "from_name": {
            "type": "string"
          },
          "has_cert": {
            "type": "boolean"
          },
          "has_logo": {
            "type": "boolean"
          },
          "logo_fixed": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "logo_url": {
            "type": "string"
          },
          "providers": {
            "$ref": "#/components/schemas/BrandProviders"
          },
          "published_bimi": {
            "type": "string"
          }
        },
        "required": [
          "bimi_record",
          "cert_url",
          "checks",
          "dmarc",
          "dmarc_record",
          "from_name",
          "has_cert",
          "has_logo",
          "logo_url",
          "providers",
          "published_bimi"
        ]
      },
      "BrandBimiRecord": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "record": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "record",
          "required",
          "status",
          "type",
          "value"
        ]
      },
      "BrandCheck": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "ok": {
            "type": "boolean"
          }
        },
        "required": [
          "detail",
          "id",
          "label",
          "ok"
        ]
      },
      "BrandDmarc": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string"
          },
          "enforced": {
            "type": "boolean"
          },
          "p": {
            "type": "string"
          },
          "pct": {
            "type": "integer"
          },
          "record": {
            "type": "string"
          },
          "sp": {
            "type": "string"
          }
        },
        "required": [
          "domain",
          "enforced",
          "p",
          "pct",
          "record",
          "sp"
        ]
      },
      "BrandDmarcRecord": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "record": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "record",
          "required",
          "status",
          "type",
          "value"
        ]
      },
      "BrandProviders": {
        "type": "object",
        "properties": {
          "apple": {
            "type": "string"
          },
          "gmail": {
            "type": "string"
          },
          "yahoo": {
            "type": "string"
          }
        },
        "required": [
          "apple",
          "gmail",
          "yahoo"
        ]
      },
      "CreatedApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "key": {
            "$ref": "#/components/schemas/CreatedApiKeyKey"
          },
          "token": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "key",
          "token"
        ]
      },
      "CreatedApiKeyKey": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "domain_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "id": {
            "type": "string"
          },
          "last_used_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "mode": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "permission": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "stream": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "created_at",
          "domain_id",
          "expires_at",
          "id",
          "last_used_at",
          "mode",
          "name",
          "permission",
          "prefix",
          "stream"
        ]
      },
      "DedicatedIp": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string"
          },
          "blocklists": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DedicatedIpBlocklist"
            }
          },
          "daily_cap": {
            "type": [
              "integer",
              "null"
            ]
          },
          "hostname": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "warmup_day": {
            "type": "integer"
          },
          "warmup_days": {
            "type": "integer"
          },
          "warmup_progress": {
            "type": "number"
          }
        },
        "required": [
          "address",
          "blocklists",
          "daily_cap",
          "hostname",
          "status",
          "warmup_day",
          "warmup_days",
          "warmup_progress"
        ]
      },
      "DedicatedIpBlocklist": {
        "type": "object",
        "properties": {
          "checked_at": {
            "type": "string",
            "format": "date-time"
          },
          "codes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "detail": {
            "type": "string"
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "type": "string"
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "list": {
            "type": "string"
          },
          "listed": {
            "type": "boolean"
          },
          "listed_since": {
            "type": "string",
            "format": "date-time"
          },
          "name": {
            "type": "string"
          },
          "removal_url": {
            "type": "string"
          },
          "severity": {
            "type": "string"
          },
          "target": {
            "type": "string"
          }
        },
        "required": [
          "checked_at",
          "codes",
          "detail",
          "error",
          "kind",
          "labels",
          "list",
          "listed",
          "listed_since",
          "name",
          "removal_url",
          "severity",
          "target"
        ]
      },
      "Deleted": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "deleted": {
            "type": "boolean"
          }
        },
        "required": [
          "object",
          "deleted"
        ]
      },
      "DmarcSummary": {
        "type": "object",
        "properties": {
          "days": {
            "type": "integer"
          },
          "domain": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "record": {
            "$ref": "#/components/schemas/DmarcSummaryRecord"
          },
          "reporters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DmarcSummaryReporter"
            }
          },
          "reports": {
            "type": "integer"
          },
          "rua": {
            "type": "string"
          },
          "series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DmarcSummarySeries"
            }
          },
          "since": {
            "type": "string",
            "format": "date-time"
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DmarcSummarySource"
            }
          },
          "totals": {
            "$ref": "#/components/schemas/DmarcSummaryTotals"
          }
        },
        "required": [
          "days",
          "domain",
          "object",
          "record",
          "reporters",
          "reports",
          "rua",
          "series",
          "since",
          "sources",
          "totals"
        ]
      },
      "DmarcSummaryRecord": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "type",
          "value"
        ]
      },
      "DmarcSummaryReporter": {
        "type": "object",
        "properties": {
          "messages": {
            "type": "integer"
          },
          "org": {
            "type": "string"
          },
          "reports": {
            "type": "integer"
          }
        },
        "required": [
          "messages",
          "org",
          "reports"
        ]
      },
      "DmarcSummarySeries": {
        "type": "object",
        "properties": {
          "day": {
            "type": "string",
            "format": "date-time"
          },
          "dkim_passed": {
            "type": "integer"
          },
          "messages": {
            "type": "integer"
          },
          "passed": {
            "type": "integer"
          },
          "quarantined": {
            "type": "integer"
          },
          "rejected": {
            "type": "integer"
          },
          "spf_passed": {
            "type": "integer"
          }
        },
        "required": [
          "day",
          "dkim_passed",
          "messages",
          "passed",
          "quarantined",
          "rejected",
          "spf_passed"
        ]
      },
      "DmarcSummarySource": {
        "type": "object",
        "properties": {
          "dkim_passed": {
            "type": "integer"
          },
          "ip": {
            "type": "string"
          },
          "messages": {
            "type": "integer"
          },
          "ours": {
            "type": "boolean"
          },
          "passed": {
            "type": "integer"
          },
          "quarantined": {
            "type": "integer"
          },
          "rejected": {
            "type": "integer"
          },
          "reporters": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "spf_passed": {
            "type": "integer"
          }
        },
        "required": [
          "dkim_passed",
          "ip",
          "messages",
          "ours",
          "passed",
          "quarantined",
          "rejected",
          "reporters",
          "spf_passed"
        ]
      },
      "DmarcSummaryTotals": {
        "type": "object",
        "properties": {
          "dkim_passed": {
            "type": "integer"
          },
          "messages": {
            "type": "integer"
          },
          "passed": {
            "type": "integer"
          },
          "quarantined": {
            "type": "integer"
          },
          "rejected": {
            "type": "integer"
          },
          "spf_passed": {
            "type": "integer"
          }
        },
        "required": [
          "dkim_passed",
          "messages",
          "passed",
          "quarantined",
          "rejected",
          "spf_passed"
        ]
      },
      "Domain": {
        "type": "object",
        "properties": {
          "brand_updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "click_tracking": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "dkim_selector": {
            "type": "string"
          },
          "dkim_verified": {
            "type": "boolean"
          },
          "dmarc_verified": {
            "type": "boolean"
          },
          "found": {
            "type": "object",
            "additionalProperties": {}
          },
          "from_name": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "last_checked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "name": {
            "type": "string"
          },
          "open_tracking": {
            "type": "boolean"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainRecord"
            }
          },
          "reply_domain": {
            "type": "string"
          },
          "reply_forward_to": {
            "type": "string"
          },
          "reply_tracking": {
            "type": "boolean"
          },
          "spf_verified": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "tls": {
            "type": "string"
          },
          "verified_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "zone": {
            "type": "string"
          }
        },
        "required": [
          "brand_updated_at",
          "click_tracking",
          "created_at",
          "dkim_selector",
          "dkim_verified",
          "dmarc_verified",
          "from_name",
          "id",
          "last_checked_at",
          "name",
          "open_tracking",
          "records",
          "reply_domain",
          "reply_forward_to",
          "reply_tracking",
          "spf_verified",
          "status",
          "tls",
          "verified_at",
          "zone"
        ]
      },
      "DomainRecord": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "record": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "record",
          "required",
          "status",
          "type",
          "value"
        ]
      },
      "DomainReputation": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainReputationEvent"
            }
          },
          "lists": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainReputationList"
            }
          },
          "object": {
            "type": "string"
          },
          "worst": {
            "type": "string"
          }
        },
        "required": [
          "domain",
          "events",
          "lists",
          "object",
          "worst"
        ]
      },
      "DomainReputationEvent": {
        "type": "object",
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "codes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "detail": {
            "type": "string"
          },
          "event": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "list": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "severity": {
            "type": [
              "string",
              "null"
            ]
          },
          "target": {
            "type": "string"
          }
        },
        "required": [
          "at",
          "codes",
          "detail",
          "event",
          "id",
          "kind",
          "list",
          "name",
          "severity",
          "target"
        ]
      },
      "DomainReputationList": {
        "type": "object",
        "properties": {
          "checked_at": {
            "type": "string",
            "format": "date-time"
          },
          "codes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "detail": {
            "type": "string"
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "type": "string"
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "list": {
            "type": "string"
          },
          "listed": {
            "type": "boolean"
          },
          "listed_since": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "name": {
            "type": "string"
          },
          "removal_url": {
            "type": "string"
          },
          "severity": {
            "type": [
              "string",
              "null"
            ]
          },
          "target": {
            "type": "string"
          }
        },
        "required": [
          "checked_at",
          "codes",
          "detail",
          "error",
          "kind",
          "labels",
          "list",
          "listed",
          "listed_since",
          "name",
          "removal_url",
          "severity",
          "target"
        ]
      },
      "Email": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "error": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailEvent"
            }
          },
          "from": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "last_event": {
            "type": "string"
          },
          "last_status": {
            "type": "string"
          },
          "metadata": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "string"
            }
          },
          "object": {
            "type": "string"
          },
          "recipients": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailRecipient"
            }
          },
          "scheduled_at": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string"
          },
          "stream": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "test": {
            "type": "boolean"
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "object"
        ]
      },
      "EmailContent": {
        "type": "object",
        "properties": {
          "bcc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "from": {
            "type": "string"
          },
          "html": {
            "type": "string"
          },
          "raw": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          },
          "source": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "tags": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "thread_id": {
            "type": "string"
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "bcc",
          "cc",
          "from",
          "html",
          "raw",
          "size",
          "source",
          "subject",
          "tags",
          "text",
          "to"
        ]
      },
      "EmailEvent": {
        "type": "object",
        "properties": {
          "attempts": {
            "type": "integer"
          },
          "egress_source": {
            "type": "string"
          },
          "mx": {
            "type": "string"
          },
          "peer_addr": {
            "type": "string"
          },
          "recipient": {
            "type": "string"
          },
          "response": {
            "type": "string"
          },
          "response_code": {
            "type": "integer"
          },
          "status": {
            "type": "string"
          },
          "time": {
            "type": "string",
            "format": "date-time"
          },
          "tls": {
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "required": [
          "attempts",
          "recipient",
          "status",
          "time",
          "type"
        ]
      },
      "EmailRecipient": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "response": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "email",
          "status",
          "updated_at"
        ]
      },
      "EmailShare": {
        "type": "object",
        "properties": {
          "email_id": {
            "type": "string"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "object": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "email_id",
          "expires_at",
          "object",
          "url"
        ]
      },
      "ForwardDestination": {
        "type": "object",
        "properties": {
          "confirmation_sent_at": {
            "type": "string",
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "email": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "verified_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "confirmation_sent_at",
          "created_at",
          "email",
          "id",
          "verified_at"
        ]
      },
      "InboundDomain": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "example_address": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "last_checked_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "managed": {
            "type": "boolean"
          },
          "mx_verified": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InboundDomainRecord"
            }
          },
          "reject_spam": {
            "type": "boolean"
          },
          "require_tls": {
            "type": "boolean"
          }
        },
        "required": [
          "created_at",
          "example_address",
          "id",
          "last_checked_at",
          "managed",
          "mx_verified",
          "name",
          "records",
          "reject_spam"
        ]
      },
      "InboundDomainCheck": {
        "type": "object",
        "properties": {
          "domain": {
            "$ref": "#/components/schemas/InboundDomainCheckDomain"
          },
          "mx_found": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "domain",
          "mx_found"
        ]
      },
      "InboundDomainCheckDomain": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "example_address": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "last_checked_at": {
            "type": "string",
            "format": "date-time"
          },
          "managed": {
            "type": "boolean"
          },
          "mx_verified": {
            "type": "boolean"
          },
          "name": {
            "type": "string"
          },
          "records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InboundDomainCheckDomainRecord"
            }
          },
          "reject_spam": {
            "type": "boolean"
          },
          "require_tls": {
            "type": "boolean"
          }
        },
        "required": [
          "created_at",
          "example_address",
          "id",
          "last_checked_at",
          "managed",
          "mx_verified",
          "name",
          "records",
          "reject_spam"
        ]
      },
      "InboundDomainCheckDomainRecord": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "record": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "record",
          "required",
          "status",
          "type",
          "value"
        ]
      },
      "InboundDomainRecord": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "record": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "record",
          "required",
          "status",
          "type",
          "value"
        ]
      },
      "InboundRoute": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "enabled": {
            "type": "boolean"
          },
          "forward_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "match_header": {
            "type": "string"
          },
          "match_header_value": {
            "type": "string"
          },
          "match_recipient": {
            "type": "string"
          },
          "match_sender": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "priority": {
            "type": "integer"
          },
          "webhook_id": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "action",
          "created_at",
          "enabled",
          "id",
          "match_header",
          "match_header_value",
          "match_recipient",
          "match_sender",
          "name",
          "priority",
          "webhook_id"
        ]
      },
      "InboundStats": {
        "type": "object",
        "properties": {
          "received": {
            "type": "integer"
          },
          "rejected": {
            "type": "integer"
          },
          "spam": {
            "type": "integer"
          }
        },
        "required": [
          "received",
          "rejected",
          "spam"
        ]
      },
      "Log": {
        "type": "object",
        "properties": {
          "api_key_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "duration_ms": {
            "type": "number"
          },
          "id": {
            "type": "string"
          },
          "ip": {
            "type": "string"
          },
          "method": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "path": {
            "type": "string"
          },
          "request_body": {
            "type": "object",
            "additionalProperties": {}
          },
          "response_body": {
            "type": "object",
            "additionalProperties": {}
          },
          "route": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "user_agent": {
            "type": "string"
          }
        },
        "required": [
          "api_key_id",
          "created_at",
          "duration_ms",
          "id",
          "ip",
          "method",
          "object",
          "path",
          "route",
          "status",
          "user_agent"
        ]
      },
      "Metrics": {
        "type": "object",
        "properties": {
          "dimension": {
            "type": "string"
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "granularity": {
            "type": "string"
          },
          "groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MetricsGroup"
            }
          },
          "object": {
            "type": "string"
          },
          "series": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MetricsSeries"
            }
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "totals": {
            "$ref": "#/components/schemas/MetricsTotals"
          }
        },
        "required": [
          "from",
          "granularity",
          "object",
          "series",
          "to",
          "totals"
        ]
      },
      "MetricsGroup": {
        "type": "object",
        "properties": {
          "bounce_rate": {
            "type": "number"
          },
          "bounced": {
            "type": "integer"
          },
          "click_rate": {
            "type": "number"
          },
          "clicked": {
            "type": "integer"
          },
          "complained": {
            "type": "integer"
          },
          "complaint_rate": {
            "type": "number"
          },
          "delayed": {
            "type": "integer"
          },
          "delivered": {
            "type": "integer"
          },
          "delivery_rate": {
            "type": "number"
          },
          "failed": {
            "type": "integer"
          },
          "human_open_rate": {
            "type": "number"
          },
          "human_opened": {
            "type": "integer"
          },
          "open_rate": {
            "type": "number"
          },
          "opened": {
            "type": "integer"
          },
          "sent": {
            "type": "integer"
          },
          "suppressed": {
            "type": "integer"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "bounce_rate",
          "bounced",
          "click_rate",
          "clicked",
          "complained",
          "complaint_rate",
          "delayed",
          "delivered",
          "delivery_rate",
          "failed",
          "human_open_rate",
          "human_opened",
          "open_rate",
          "opened",
          "sent",
          "suppressed",
          "value"
        ]
      },
      "MetricsSeries": {
        "type": "object",
        "properties": {
          "bounce_rate": {
            "type": "number"
          },
          "bounced": {
            "type": "integer"
          },
          "click_rate": {
            "type": "number"
          },
          "clicked": {
            "type": "integer"
          },
          "complained": {
            "type": "integer"
          },
          "complaint_rate": {
            "type": "number"
          },
          "delayed": {
            "type": "integer"
          },
          "delivered": {
            "type": "integer"
          },
          "delivery_rate": {
            "type": "number"
          },
          "failed": {
            "type": "integer"
          },
          "human_open_rate": {
            "type": "number"
          },
          "human_opened": {
            "type": "integer"
          },
          "open_rate": {
            "type": "number"
          },
          "opened": {
            "type": "integer"
          },
          "sent": {
            "type": "integer"
          },
          "suppressed": {
            "type": "integer"
          },
          "time": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "bounce_rate",
          "bounced",
          "click_rate",
          "clicked",
          "complained",
          "complaint_rate",
          "delayed",
          "delivered",
          "delivery_rate",
          "failed",
          "human_open_rate",
          "human_opened",
          "open_rate",
          "opened",
          "sent",
          "suppressed",
          "time"
        ]
      },
      "MetricsTotals": {
        "type": "object",
        "properties": {
          "bounce_rate": {
            "type": "number"
          },
          "bounced": {
            "type": "integer"
          },
          "click_rate": {
            "type": "number"
          },
          "clicked": {
            "type": "integer"
          },
          "complained": {
            "type": "integer"
          },
          "complaint_rate": {
            "type": "number"
          },
          "delayed": {
            "type": "integer"
          },
          "delivered": {
            "type": "integer"
          },
          "delivery_rate": {
            "type": "number"
          },
          "failed": {
            "type": "integer"
          },
          "human_open_rate": {
            "type": "number"
          },
          "human_opened": {
            "type": "integer"
          },
          "open_rate": {
            "type": "number"
          },
          "opened": {
            "type": "integer"
          },
          "sent": {
            "type": "integer"
          },
          "suppressed": {
            "type": "integer"
          }
        },
        "required": [
          "bounce_rate",
          "bounced",
          "click_rate",
          "clicked",
          "complained",
          "complaint_rate",
          "delayed",
          "delivered",
          "delivery_rate",
          "failed",
          "human_open_rate",
          "human_opened",
          "open_rate",
          "opened",
          "sent",
          "suppressed"
        ]
      },
      "ReceivedEmail": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string"
          },
          "arc": {
            "type": "string"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceivedEmailAttachment"
            }
          },
          "authentication": {
            "$ref": "#/components/schemas/ReceivedEmailAuthentication"
          },
          "automated": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReceivedEmailAutomated"
              },
              {
                "type": "null"
              }
            ]
          },
          "bcc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "envelope": {
            "$ref": "#/components/schemas/ReceivedEmailEnvelope"
          },
          "from": {
            "type": "string"
          },
          "from_name": {
            "type": "string"
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "helo": {
            "type": "string"
          },
          "html": {
            "type": [
              "string",
              "null"
            ]
          },
          "html_format": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "in_reply_to_email_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_spam": {
            "type": "boolean"
          },
          "mailbox_hash": {
            "type": "string"
          },
          "message_id": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "peer_ip": {
            "type": "string"
          },
          "raw": {
            "$ref": "#/components/schemas/ReceivedEmailRaw"
          },
          "received_for": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "reply_text": {
            "type": "string"
          },
          "reply_to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "route_id": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          },
          "spam": {
            "$ref": "#/components/schemas/ReceivedEmailSpam"
          },
          "spam_score": {
            "type": "number"
          },
          "status": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "thread_id": {
            "type": "string"
          },
          "tls": {
            "type": "string"
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "action",
          "attachments",
          "bcc",
          "cc",
          "created_at",
          "from",
          "from_name",
          "id",
          "message_id",
          "object",
          "received_for",
          "reply_to",
          "size",
          "status",
          "subject",
          "to"
        ]
      },
      "ReceivedEmailAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "learned": {
            "type": "boolean"
          },
          "object": {
            "type": "string"
          },
          "redelivered": {
            "type": "boolean"
          },
          "spam": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "object"
        ]
      },
      "ReceivedEmailAttachment": {
        "type": "object",
        "properties": {
          "content_disposition": {
            "type": "string"
          },
          "content_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "content_type": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          }
        },
        "required": [
          "id"
        ]
      },
      "ReceivedEmailAuthentication": {
        "type": "object",
        "properties": {
          "dkim": {
            "type": "string"
          },
          "dmarc": {
            "type": "string"
          },
          "spf": {
            "type": "string"
          }
        },
        "required": [
          "dkim",
          "dmarc",
          "spf"
        ]
      },
      "ReceivedEmailAutomated": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "required": [
          "reason",
          "type"
        ]
      },
      "ReceivedEmailEnvelope": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string"
          },
          "to": {
            "type": "string"
          }
        },
        "required": [
          "from",
          "to"
        ]
      },
      "ReceivedEmailRaw": {
        "type": "object",
        "properties": {
          "download_url": {
            "type": "string"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "download_url",
          "expires_at"
        ]
      },
      "ReceivedEmailSpam": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string"
          },
          "is_spam": {
            "type": "boolean"
          },
          "score": {
            "type": "number"
          }
        },
        "required": [
          "action",
          "is_spam",
          "score"
        ]
      },
      "RenderedTemplate": {
        "type": "object",
        "properties": {
          "design": {},
          "html": {
            "type": "string"
          },
          "missing_variables": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "variable_names": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "html",
          "missing_variables",
          "subject",
          "text",
          "variable_names"
        ]
      },
      "SendBatchResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SendBatchResponseData"
            }
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SendBatchResponseError"
            }
          }
        },
        "required": [
          "data",
          "errors"
        ]
      },
      "SendBatchResponseData": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "index": {
            "type": "integer"
          },
          "reply_to": {
            "type": "string"
          },
          "suppressed": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "thread_id": {
            "type": "string"
          },
          "unconfirmed": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "index"
        ]
      },
      "SendBatchResponseError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "index": {
            "type": "integer"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "index",
          "message"
        ]
      },
      "SendEmailResponse": {
        "type": "object",
        "properties": {
          "failed_recipients": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "id": {
            "type": "string"
          },
          "reply_to": {
            "type": "string"
          },
          "suppressed": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "thread_id": {
            "type": "string"
          },
          "unconfirmed": {
            "type": "boolean"
          }
        },
        "required": [
          "id"
        ]
      },
      "Simulator": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string"
          },
          "note": {
            "type": "string"
          },
          "scenarios": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SimulatorScenario"
            }
          }
        },
        "required": [
          "domain",
          "note",
          "scenarios"
        ]
      },
      "SimulatorScenario": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string"
          },
          "event": {
            "type": "string"
          },
          "result": {
            "type": "string"
          }
        },
        "required": [
          "address",
          "event",
          "result"
        ]
      },
      "SmtpCredential": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "domain_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "password": {
            "type": "string"
          },
          "settings": {
            "$ref": "#/components/schemas/SmtpCredentialSettings"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "created_at",
          "domain_id",
          "id",
          "name",
          "password",
          "settings",
          "username"
        ]
      },
      "SmtpCredentialList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SmtpCredentialListData"
            }
          },
          "limit": {
            "type": "integer"
          },
          "object": {
            "type": "string"
          },
          "settings": {
            "$ref": "#/components/schemas/SmtpCredentialListSettings"
          }
        },
        "required": [
          "data",
          "limit",
          "object",
          "settings"
        ]
      },
      "SmtpCredentialListData": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "domain_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "id": {
            "type": "string"
          },
          "last_used_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "name": {
            "type": "string"
          },
          "username": {
            "type": "string"
          }
        },
        "required": [
          "created_at",
          "domain_id",
          "id",
          "last_used_at",
          "name",
          "username"
        ]
      },
      "SmtpCredentialListSettings": {
        "type": "object",
        "properties": {
          "host": {
            "type": "string"
          },
          "mechanisms": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ports": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        },
        "required": [
          "host",
          "mechanisms",
          "ports"
        ]
      },
      "SmtpCredentialSettings": {
        "type": "object",
        "properties": {
          "host": {
            "type": "string"
          },
          "mechanisms": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ports": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        },
        "required": [
          "host",
          "mechanisms",
          "ports"
        ]
      },
      "SpamCheck": {
        "type": "object",
        "properties": {
          "dkim_signed": {
            "type": "boolean"
          },
          "email_id": {
            "type": "string"
          },
          "engines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpamCheckEngine"
            }
          },
          "issues": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpamCheckIssue"
            }
          },
          "note": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "score": {
            "type": "number"
          },
          "sending_ip": {
            "type": "string"
          },
          "threshold": {
            "type": "number"
          },
          "verdict": {
            "type": "string"
          }
        },
        "required": [
          "dkim_signed",
          "engines",
          "issues",
          "note",
          "object",
          "score",
          "sending_ip",
          "threshold",
          "verdict"
        ]
      },
      "SpamCheckEngine": {
        "type": "object",
        "properties": {
          "engine": {
            "type": "string"
          },
          "error": {
            "type": "string"
          },
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpamCheckEngineRule"
            }
          },
          "score": {
            "type": "number"
          },
          "threshold": {
            "type": "number"
          },
          "verdict": {
            "type": "string"
          }
        },
        "required": [
          "engine",
          "rules",
          "score",
          "threshold",
          "verdict"
        ]
      },
      "SpamCheckEngineRule": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "score": {
            "type": "number"
          }
        },
        "required": [
          "name",
          "score"
        ]
      },
      "SpamCheckIssue": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "kind",
          "message"
        ]
      },
      "Stats": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsData"
            }
          },
          "hours": {
            "type": "integer"
          }
        },
        "required": [
          "data",
          "hours"
        ]
      },
      "StatsBreakdown": {
        "type": "object",
        "properties": {
          "bounces": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsBreakdownBounce"
            }
          },
          "engagement": {
            "$ref": "#/components/schemas/StatsBreakdownEngagement"
          },
          "providers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsBreakdownProvider"
            }
          },
          "top_links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsBreakdownTopLink"
            }
          }
        },
        "required": [
          "bounces",
          "engagement",
          "providers",
          "top_links"
        ]
      },
      "StatsBreakdownBounce": {
        "type": "object",
        "properties": {
          "classification": {
            "type": "string"
          },
          "count": {
            "type": "integer"
          }
        },
        "required": [
          "classification",
          "count"
        ]
      },
      "StatsBreakdownEngagement": {
        "type": "object",
        "properties": {
          "clicks": {
            "type": "integer"
          },
          "delivered": {
            "type": "integer"
          },
          "human_unique_opens": {
            "type": "integer"
          },
          "machine_opens": {
            "type": "integer"
          },
          "opens": {
            "type": "integer"
          },
          "unique_clicks": {
            "type": "integer"
          },
          "unique_opens": {
            "type": "integer"
          }
        },
        "required": [
          "clicks",
          "delivered",
          "human_unique_opens",
          "machine_opens",
          "opens",
          "unique_clicks",
          "unique_opens"
        ]
      },
      "StatsBreakdownProvider": {
        "type": "object",
        "properties": {
          "bounced": {
            "type": "integer"
          },
          "complained": {
            "type": "integer"
          },
          "delayed": {
            "type": "integer"
          },
          "delivered": {
            "type": "integer"
          },
          "provider": {
            "type": "string"
          },
          "sent": {
            "type": "integer"
          }
        },
        "required": [
          "bounced",
          "complained",
          "delayed",
          "delivered",
          "provider",
          "sent"
        ]
      },
      "StatsBreakdownTopLink": {
        "type": "object",
        "properties": {
          "clicks": {
            "type": "integer"
          },
          "unique": {
            "type": "integer"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "clicks",
          "unique",
          "url"
        ]
      },
      "StatsData": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "count",
          "status"
        ]
      },
      "StatsTimeseries": {
        "type": "object",
        "properties": {
          "bucket_seconds": {
            "type": "integer"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatsTimeseriesData"
            }
          },
          "hours": {
            "type": "integer"
          },
          "since": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "bucket_seconds",
          "data",
          "hours",
          "since"
        ]
      },
      "StatsTimeseriesData": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "status": {
            "type": "string"
          },
          "t": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "count",
          "status",
          "t"
        ]
      },
      "Suppression": {
        "type": "object",
        "properties": {
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "email": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "source_id": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "email",
          "reason"
        ]
      },
      "SuppressionBatch": {
        "type": "object",
        "properties": {
          "added": {
            "type": "integer"
          },
          "emails": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "object": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "removed": {
            "type": "integer"
          }
        },
        "required": [
          "emails",
          "object"
        ]
      },
      "Template": {
        "type": "object",
        "properties": {
          "alias": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "design": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {}
          },
          "from": {
            "type": "string"
          },
          "has_unpublished_changes": {
            "type": "boolean"
          },
          "html": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "published": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TemplatePublished"
              },
              {
                "type": "null"
              }
            ]
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "status": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "variable_names": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "variable_schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateVariableSchema"
            }
          },
          "variables": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        },
        "required": [
          "alias",
          "id",
          "name",
          "object"
        ]
      },
      "TemplateAsset": {
        "type": "object",
        "properties": {
          "content_type": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "ext": {
            "type": "string"
          },
          "height": {
            "type": "integer"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          },
          "url": {
            "type": "string"
          },
          "width": {
            "type": "integer"
          }
        },
        "required": [
          "content_type",
          "created_at",
          "ext",
          "height",
          "id",
          "name",
          "object",
          "size",
          "url",
          "width"
        ]
      },
      "TemplateModule": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "design": {
            "type": "object",
            "additionalProperties": {}
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "category",
          "created_at",
          "design",
          "id",
          "name",
          "updated_at"
        ]
      },
      "TemplatePublished": {
        "type": "object",
        "properties": {
          "design": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {}
          },
          "from": {
            "type": "string"
          },
          "html": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "variable_schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplatePublishedVariableSchema"
            }
          }
        },
        "required": [
          "design",
          "from",
          "html",
          "subject",
          "text"
        ]
      },
      "TemplatePublishedVariableSchema": {
        "type": "object",
        "properties": {
          "default": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "example": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "type": {
            "type": "string"
          },
          "unused": {
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "required",
          "type"
        ]
      },
      "TemplateTimer": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "object",
          "url"
        ]
      },
      "TemplateVariableSchema": {
        "type": "object",
        "properties": {
          "default": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "example": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "type": {
            "type": "string"
          },
          "unused": {
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "required",
          "type"
        ]
      },
      "TemplateVersion": {
        "type": "object",
        "properties": {
          "author": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "from": {
            "type": "string"
          },
          "html": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        },
        "required": [
          "author",
          "created_at",
          "id",
          "kind",
          "name",
          "subject"
        ]
      },
      "Thread": {
        "type": "object",
        "properties": {
          "awaiting_reply": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadData"
            }
          },
          "first_message_at": {
            "type": "string",
            "format": "date-time"
          },
          "has_attachments": {
            "type": "boolean"
          },
          "has_more": {
            "type": "boolean"
          },
          "id": {
            "type": "string"
          },
          "inbound_count": {
            "type": "integer"
          },
          "last_inbound_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_message": {
            "$ref": "#/components/schemas/ThreadLastMessage"
          },
          "last_message_at": {
            "type": "string",
            "format": "date-time"
          },
          "message_count": {
            "type": "integer"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "object": {
            "type": "string"
          },
          "outbound_count": {
            "type": "integer"
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "read_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "subject": {
            "type": "string"
          },
          "unread": {
            "type": "boolean"
          }
        },
        "required": [
          "awaiting_reply",
          "first_message_at",
          "has_attachments",
          "id",
          "inbound_count",
          "last_inbound_at",
          "last_message",
          "last_message_at",
          "message_count",
          "metadata",
          "object",
          "outbound_count",
          "participants",
          "read_at",
          "subject",
          "unread"
        ]
      },
      "ThreadData": {
        "type": "object",
        "properties": {
          "automated": {
            "type": "string"
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "direction": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "message_id": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "cc",
          "created_at",
          "direction",
          "from",
          "id",
          "object",
          "subject",
          "to"
        ]
      },
      "ThreadLastMessage": {
        "type": "object",
        "properties": {
          "direction": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          }
        },
        "required": [
          "direction",
          "from",
          "id",
          "subject"
        ]
      },
      "Usage": {
        "type": "object",
        "properties": {
          "included": {
            "type": "integer"
          },
          "limit": {
            "type": [
              "integer",
              "null"
            ]
          },
          "month": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "overage_cents": {
            "type": "integer"
          },
          "overage_emails": {
            "type": "integer"
          },
          "plan": {
            "$ref": "#/components/schemas/UsagePlan"
          },
          "sent": {
            "type": "integer"
          }
        },
        "required": [
          "included",
          "limit",
          "month",
          "object",
          "overage_cents",
          "overage_emails",
          "plan",
          "sent"
        ]
      },
      "UsagePlan": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "retention_days": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "name",
          "retention_days"
        ]
      },
      "Variable": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "key": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "object": {
            "type": "string"
          },
          "templates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VariableTemplate"
            }
          },
          "type": {
            "type": "string"
          },
          "types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "kind",
          "name",
          "object",
          "templates"
        ]
      },
      "VariableTemplate": {
        "type": "object",
        "properties": {
          "default": {
            "type": "string"
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "type": {
            "type": "string"
          },
          "unused": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "batch": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "disabled_reason": {
            "type": [
              "string",
              "null"
            ]
          },
          "enabled": {
            "type": "boolean"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "filter": {
            "$ref": "#/components/schemas/WebhookFilter"
          },
          "id": {
            "type": "string"
          },
          "include_content": {
            "type": "boolean"
          },
          "object": {
            "type": "string"
          },
          "previous_secret_expires_at": {
            "type": "string",
            "format": "date-time"
          },
          "secret": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ]
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "attempt": {
            "type": "integer"
          },
          "body": {
            "type": "object",
            "additionalProperties": {}
          },
          "duration_ms": {
            "type": "number"
          },
          "error": {
            "type": "string"
          },
          "event_id": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "status_code": {
            "type": "integer"
          }
        },
        "required": [
          "at",
          "attempt",
          "body",
          "duration_ms",
          "event_id",
          "event_type",
          "status_code"
        ]
      },
      "WebhookEventRecord": {
        "type": "object",
        "properties": {
          "attempt_list": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventRecordAttemptList"
            }
          },
          "attempts": {
            "type": "integer"
          },
          "first_attempt_at": {
            "type": "string",
            "format": "date-time"
          },
          "id": {
            "type": "string"
          },
          "last_attempt_at": {
            "type": "string",
            "format": "date-time"
          },
          "last_error": {
            "type": "string"
          },
          "last_status_code": {
            "type": "integer"
          },
          "object": {
            "type": "string"
          },
          "payload": {
            "type": "object",
            "additionalProperties": {}
          },
          "status": {
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "required": [
          "attempts",
          "first_attempt_at",
          "id",
          "last_attempt_at",
          "last_status_code",
          "object",
          "status",
          "type"
        ]
      },
      "WebhookEventRecordAttemptList": {
        "type": "object",
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "attempt": {
            "type": "integer"
          },
          "duration_ms": {
            "type": "number"
          },
          "error": {
            "type": "string"
          },
          "status_code": {
            "type": "integer"
          }
        },
        "required": [
          "at",
          "attempt",
          "duration_ms",
          "status_code"
        ]
      },
      "WebhookTestResult": {
        "type": "object",
        "properties": {
          "delivery": {
            "$ref": "#/components/schemas/WebhookTestResultDelivery"
          },
          "ok": {
            "type": "boolean"
          },
          "payload": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "delivery",
          "ok"
        ]
      },
      "WebhookTestResultDelivery": {
        "type": "object",
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "attempt": {
            "type": "integer"
          },
          "body": {
            "type": "object",
            "additionalProperties": {}
          },
          "duration_ms": {
            "type": "number"
          },
          "error": {
            "type": "string"
          },
          "event_id": {
            "type": "string"
          },
          "event_type": {
            "type": "string"
          },
          "status_code": {
            "type": "integer"
          }
        },
        "required": [
          "at",
          "attempt",
          "body",
          "duration_ms",
          "event_id",
          "event_type",
          "status_code"
        ]
      }
    }
  }
}