{
  "openapi": "3.1.0",
  "info": {
    "title": "Postkit API",
    "description": "The European Email API for Developers.\nEU-hosted, GDPR-native, Resend-compatible.\n\n## Authentication\nAll requests require a Bearer token in the Authorization header:\n```\nAuthorization: Bearer pk_live_xxxxxxxxx\n```\n\nAPI Keys use the prefix `pk_live_` for production and `pk_test_` for sandbox mode.\nTest mode keys simulate all operations without delivering actual emails.\n\n## Rate Limits\nDefault: 10 requests/second per organization.\nBatch endpoint: 2 requests/second.\nRate limit headers are included in every response.\n\n## Pagination\nList endpoints use cursor-based pagination with `starting_after` and `ending_before` parameters.\n\n## Errors\nAll errors return a consistent JSON structure with `error.type`, `error.message`, and `error.code`.\n\n## Data Residency\nAll data is processed and stored exclusively in the European Union.\n",
    "version": "1.0.0",
    "contact": {
      "name": "Postkit Support",
      "email": "support@postkit.eu",
      "url": "https://postkit.eu"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://postkit.eu/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.postkit.eu/v1",
      "description": "Production (EU)"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Emails",
      "description": "Send and manage transactional emails"
    },
    {
      "name": "Receiving",
      "description": "Retrieve and manage inbound emails"
    },
    {
      "name": "Domains",
      "description": "Domain verification and DNS management"
    },
    {
      "name": "API Keys",
      "description": "Create and manage API keys"
    },
    {
      "name": "Webhooks",
      "description": "Configure webhook endpoints for real-time events"
    },
    {
      "name": "Templates",
      "description": "Create and manage email templates"
    },
    {
      "name": "Suppressions",
      "description": "Manage suppression lists"
    },
    {
      "name": "Contacts",
      "description": "Manage contacts and audiences"
    },
    {
      "name": "Audiences",
      "description": "Group contacts into audiences"
    },
    {
      "name": "Topics",
      "description": "Manage subscription topics"
    },
    {
      "name": "Broadcasts",
      "description": "Send campaigns to audiences"
    }
  ],
  "paths": {
    "/emails": {
      "post": {
        "operationId": "sendEmail",
        "tags": [
          "Emails"
        ],
        "summary": "Send an email",
        "description": "Send a single transactional email. Supports HTML, plain text, or template-based content.\nUse `send_at` for scheduled delivery. Use `Idempotency-Key` header to prevent duplicates.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendEmailRequest"
              },
              "examples": {
                "simple_html": {
                  "summary": "Simple HTML email",
                  "value": {
                    "from": "Acme <noreply@acme.eu>",
                    "to": [
                      "user@example.com"
                    ],
                    "subject": "Welcome to Acme",
                    "html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>"
                  }
                },
                "with_template": {
                  "summary": "Using a template",
                  "value": {
                    "from": "Acme <noreply@acme.eu>",
                    "to": [
                      "user@example.com"
                    ],
                    "subject": "Your order confirmation",
                    "template_id": "tmpl_abc123",
                    "template_data": {
                      "order_id": "ORD-4821",
                      "customer_name": "Max Mustermann",
                      "total": "49.99 EUR"
                    }
                  }
                },
                "scheduled": {
                  "summary": "Scheduled delivery",
                  "value": {
                    "from": "Acme <noreply@acme.eu>",
                    "to": [
                      "user@example.com"
                    ],
                    "subject": "Weekly digest",
                    "html": "<p>Your weekly summary...</p>",
                    "send_at": "2026-03-15T09:00:00Z"
                  }
                },
                "with_attachments": {
                  "summary": "With attachments",
                  "value": {
                    "from": "Acme <billing@acme.eu>",
                    "to": [
                      "user@example.com"
                    ],
                    "subject": "Your invoice",
                    "html": "<p>Please find your invoice attached.</p>",
                    "attachments": [
                      {
                        "filename": "invoice-2026-03.pdf",
                        "content": "JVBERi0xLjQK...",
                        "content_type": "application/pdf"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email accepted for delivery",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SendEmailResponse"
                },
                "example": {
                  "id": "em_a1b2c3d4e5",
                  "status": "queued"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "cURL",
            "source": "curl -X POST https://api.postkit.eu/v1/emails \\\n  -H \"Authorization: Bearer pk_live_...\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"from\": \"Acme <noreply@acme.eu>\",\n    \"to\": [\"user@example.com\"],\n    \"subject\": \"Welcome to Acme\",\n    \"html\": \"<h1>Hello from Postkit</h1><p>Your account is ready.</p>\"\n  }'\n"
          },
          {
            "lang": "TypeScript",
            "label": "TypeScript",
            "source": "const response = await fetch('https://api.postkit.eu/v1/emails', {\n  method: 'POST',\n  headers: {\n    'Authorization': 'Bearer pk_live_...',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    from: 'Acme <noreply@acme.eu>',\n    to: ['user@example.com'],\n    subject: 'Welcome to Acme',\n    html: '<h1>Hello from Postkit</h1><p>Your account is ready.</p>',\n  }),\n});\nconst email = await response.json();\n"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    'https://api.postkit.eu/v1/emails',\n    headers={'Authorization': 'Bearer pk_live_...'},\n    json={\n        'from': 'Acme <noreply@acme.eu>',\n        'to': ['user@example.com'],\n        'subject': 'Welcome to Acme',\n        'html': '<h1>Hello from Postkit</h1><p>Your account is ready.</p>',\n    },\n)\nemail = response.json()\n"
          }
        ]
      },
      "get": {
        "operationId": "listEmails",
        "tags": [
          "Emails"
        ],
        "summary": "List sent emails",
        "description": "Returns a paginated list of sent emails for the current organization.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "queued",
                "scheduled",
                "sending",
                "sent",
                "delivered",
                "bounced",
                "complained",
                "canceled"
              ]
            }
          },
          {
            "name": "domain",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by sending domain"
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by tag"
          },
          {
            "name": "from_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of emails",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmailList"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "cURL",
            "source": "curl https://api.postkit.eu/v1/emails?limit=10 \\\n  -H \"Authorization: Bearer pk_live_...\"\n"
          },
          {
            "lang": "TypeScript",
            "label": "TypeScript",
            "source": "const response = await fetch('https://api.postkit.eu/v1/emails?limit=10', {\n  headers: {\n    'Authorization': 'Bearer pk_live_...',\n  },\n});\nconst { data, has_more } = await response.json();\n"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.get(\n    'https://api.postkit.eu/v1/emails',\n    headers={'Authorization': 'Bearer pk_live_...'},\n    params={'limit': 10},\n)\nresult = response.json()\n"
          }
        ]
      }
    },
    "/emails/batch": {
      "post": {
        "operationId": "sendBatchEmails",
        "tags": [
          "Emails"
        ],
        "summary": "Send a batch of emails",
        "description": "Send up to 100 emails in a single API call. Each email is processed independently.\nReturns an array of results in the same order as the input.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/SendEmailRequest"
                },
                "minItems": 1,
                "maxItems": 100
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Batch accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SendEmailResponse"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "cURL",
            "source": "curl -X POST https://api.postkit.eu/v1/emails/batch \\\n  -H \"Authorization: Bearer pk_live_...\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '[\n    {\n      \"from\": \"Acme <noreply@acme.eu>\",\n      \"to\": [\"alice@example.com\"],\n      \"subject\": \"Welcome Alice\",\n      \"html\": \"<h1>Hello Alice</h1>\"\n    },\n    {\n      \"from\": \"Acme <noreply@acme.eu>\",\n      \"to\": [\"bob@example.com\"],\n      \"subject\": \"Welcome Bob\",\n      \"html\": \"<h1>Hello Bob</h1>\"\n    }\n  ]'\n"
          },
          {
            "lang": "TypeScript",
            "label": "TypeScript",
            "source": "const response = await fetch('https://api.postkit.eu/v1/emails/batch', {\n  method: 'POST',\n  headers: {\n    'Authorization': 'Bearer pk_live_...',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify([\n    {\n      from: 'Acme <noreply@acme.eu>',\n      to: ['alice@example.com'],\n      subject: 'Welcome Alice',\n      html: '<h1>Hello Alice</h1>',\n    },\n    {\n      from: 'Acme <noreply@acme.eu>',\n      to: ['bob@example.com'],\n      subject: 'Welcome Bob',\n      html: '<h1>Hello Bob</h1>',\n    },\n  ]),\n});\nconst result = await response.json();\n"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    'https://api.postkit.eu/v1/emails/batch',\n    headers={'Authorization': 'Bearer pk_live_...'},\n    json=[\n        {\n            'from': 'Acme <noreply@acme.eu>',\n            'to': ['alice@example.com'],\n            'subject': 'Welcome Alice',\n            'html': '<h1>Hello Alice</h1>',\n        },\n        {\n            'from': 'Acme <noreply@acme.eu>',\n            'to': ['bob@example.com'],\n            'subject': 'Welcome Bob',\n            'html': '<h1>Hello Bob</h1>',\n        },\n    ],\n)\nresult = response.json()\n"
          }
        ]
      }
    },
    "/emails/{email_id}": {
      "get": {
        "operationId": "retrieveEmail",
        "tags": [
          "Emails"
        ],
        "summary": "Retrieve a sent email",
        "description": "Returns the details and delivery status of a sent email.",
        "parameters": [
          {
            "$ref": "#/components/parameters/EmailId"
          }
        ],
        "responses": {
          "200": {
            "description": "Email details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Email"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "operationId": "updateEmail",
        "tags": [
          "Emails"
        ],
        "summary": "Update a scheduled email",
        "description": "Update the scheduled delivery time. Only works for emails with status `scheduled`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/EmailId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "send_at": {
                    "type": "string",
                    "format": "date-time",
                    "description": "New scheduled delivery time (ISO 8601)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Email updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Email"
                }
              }
            }
          },
          "409": {
            "description": "Email cannot be updated (already sent or canceled)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/{email_id}/cancel": {
      "post": {
        "operationId": "cancelEmail",
        "tags": [
          "Emails"
        ],
        "summary": "Cancel a scheduled email",
        "description": "Cancel a scheduled email before it is sent. Only works for emails with status `scheduled`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/EmailId"
          }
        ],
        "responses": {
          "200": {
            "description": "Email canceled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Email"
                },
                "example": {
                  "id": "em_a1b2c3d4e5",
                  "status": "canceled"
                }
              }
            }
          },
          "409": {
            "description": "Email cannot be canceled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/emails/{email_id}/attachments": {
      "get": {
        "operationId": "listEmailAttachments",
        "tags": [
          "Emails"
        ],
        "summary": "List attachments of a sent email",
        "parameters": [
          {
            "$ref": "#/components/parameters/EmailId"
          }
        ],
        "responses": {
          "200": {
            "description": "List of attachments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Attachment"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/emails/{email_id}/attachments/{attachment_id}": {
      "get": {
        "operationId": "retrieveEmailAttachment",
        "tags": [
          "Emails"
        ],
        "summary": "Retrieve an attachment",
        "description": "Returns attachment metadata and a time-limited download URL.",
        "parameters": [
          {
            "$ref": "#/components/parameters/EmailId"
          },
          {
            "$ref": "#/components/parameters/AttachmentId"
          }
        ],
        "responses": {
          "200": {
            "description": "Attachment details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentDetail"
                }
              }
            }
          }
        }
      }
    },
    "/emails/received": {
      "get": {
        "operationId": "listReceivedEmails",
        "tags": [
          "Receiving"
        ],
        "summary": "List received emails",
        "description": "Returns a paginated list of inbound emails.",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "$ref": "#/components/parameters/EndingBefore"
          },
          {
            "name": "domain",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by receiving domain"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by sender address"
          },
          {
            "name": "from_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to_date",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of received emails",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceivedEmailList"
                }
              }
            }
          }
        }
      }
    },
    "/emails/received/{email_id}": {
      "get": {
        "operationId": "retrieveReceivedEmail",
        "tags": [
          "Receiving"
        ],
        "summary": "Retrieve a received email",
        "description": "Returns the fully parsed content of an inbound email including headers, body, and metadata.",
        "parameters": [
          {
            "$ref": "#/components/parameters/EmailId"
          }
        ],
        "responses": {
          "200": {
            "description": "Received email details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceivedEmail"
                },
                "example": {
                  "id": "in_x9y8z7w6",
                  "from": {
                    "email": "customer@example.com",
                    "name": "Jane Doe"
                  },
                  "to": [
                    {
                      "email": "support@acme.inbound.postkit.eu"
                    }
                  ],
                  "subject": "Question about my order",
                  "text_body": "Hi, I have a question about order ORD-4821...",
                  "html_body": "<p>Hi, I have a question about order ORD-4821...</p>",
                  "headers": {
                    "message-id": "<abc123@example.com>",
                    "date": "Thu, 12 Mar 2026 10:30:00 +0100"
                  },
                  "spam_score": 0.2,
                  "is_spam": false,
                  "attachment_count": 1,
                  "created_at": "2026-03-12T09:30:05Z"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/emails/received/{email_id}/attachments": {
      "get": {
        "operationId": "listReceivedEmailAttachments",
        "tags": [
          "Receiving"
        ],
        "summary": "List attachments of a received email",
        "parameters": [
          {
            "$ref": "#/components/parameters/EmailId"
          }
        ],
        "responses": {
          "200": {
            "description": "List of attachments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Attachment"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/emails/received/{email_id}/attachments/{attachment_id}": {
      "get": {
        "operationId": "retrieveReceivedEmailAttachment",
        "tags": [
          "Receiving"
        ],
        "summary": "Retrieve an inbound attachment",
        "parameters": [
          {
            "$ref": "#/components/parameters/EmailId"
          },
          {
            "$ref": "#/components/parameters/AttachmentId"
          }
        ],
        "responses": {
          "200": {
            "description": "Attachment details with download URL",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentDetail"
                }
              }
            }
          }
        }
      }
    },
    "/domains": {
      "post": {
        "operationId": "createDomain",
        "tags": [
          "Domains"
        ],
        "summary": "Create a domain",
        "description": "Register a new sending domain. Returns the DNS records that must be configured\nfor domain verification (DKIM, SPF, DMARC, optional MX for inbound).\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDomainRequest"
              },
              "example": {
                "name": "acme.eu",
                "region": "eu",
                "open_tracking": true,
                "click_tracking": true,
                "inbound_enabled": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Domain created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                },
                "example": {
                  "id": "dom_k3j2h1g0",
                  "name": "acme.eu",
                  "status": "pending",
                  "region": "eu",
                  "open_tracking": true,
                  "click_tracking": true,
                  "inbound_enabled": false,
                  "dns_records": [
                    {
                      "type": "TXT",
                      "name": "postkit._domainkey.acme.eu",
                      "value": "v=DKIM1; k=rsa; p=MIIBIjAN...",
                      "purpose": "dkim",
                      "status": "pending"
                    },
                    {
                      "type": "TXT",
                      "name": "acme.eu",
                      "value": "v=spf1 include:spf.postkit.eu ~all",
                      "purpose": "spf",
                      "status": "pending"
                    },
                    {
                      "type": "TXT",
                      "name": "_dmarc.acme.eu",
                      "value": "v=DMARC1; p=none; rua=mailto:dmarc@postkit.eu",
                      "purpose": "dmarc",
                      "status": "pending"
                    },
                    {
                      "type": "CNAME",
                      "name": "tracking.acme.eu",
                      "value": "track.postkit.eu",
                      "purpose": "tracking",
                      "status": "pending"
                    }
                  ],
                  "created_at": "2026-03-12T10:00:00Z"
                }
              }
            }
          },
          "409": {
            "description": "Domain already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listDomains",
        "tags": [
          "Domains"
        ],
        "summary": "List domains",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          }
        ],
        "responses": {
          "200": {
            "description": "List of domains",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Domain"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/domains/{domain_id}": {
      "get": {
        "operationId": "retrieveDomain",
        "tags": [
          "Domains"
        ],
        "summary": "Retrieve a domain",
        "parameters": [
          {
            "$ref": "#/components/parameters/DomainId"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      },
      "patch": {
        "operationId": "updateDomain",
        "tags": [
          "Domains"
        ],
        "summary": "Update domain settings",
        "parameters": [
          {
            "$ref": "#/components/parameters/DomainId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "open_tracking": {
                    "type": "boolean"
                  },
                  "click_tracking": {
                    "type": "boolean"
                  },
                  "inbound_enabled": {
                    "type": "boolean"
                  },
                  "impressum": {
                    "$ref": "#/components/schemas/Impressum"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Domain updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteDomain",
        "tags": [
          "Domains"
        ],
        "summary": "Delete a domain",
        "description": "Soft-deletes the domain. A 30-day grace period applies before permanent removal.",
        "parameters": [
          {
            "$ref": "#/components/parameters/DomainId"
          }
        ],
        "responses": {
          "200": {
            "description": "Domain deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/domains/{domain_id}/verify": {
      "post": {
        "operationId": "verifyDomain",
        "tags": [
          "Domains"
        ],
        "summary": "Verify domain DNS records",
        "description": "Triggers an immediate DNS check for all required records.\nReturns the updated verification status for each record.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/DomainId"
          }
        ],
        "responses": {
          "200": {
            "description": "Verification result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Domain"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "cURL",
            "source": "curl -X POST https://api.postkit.eu/v1/domains/dom_abc123/verify \\\n  -H \"Authorization: Bearer pk_live_...\"\n"
          },
          {
            "lang": "TypeScript",
            "label": "TypeScript",
            "source": "const response = await fetch(\n  'https://api.postkit.eu/v1/domains/dom_abc123/verify',\n  {\n    method: 'POST',\n    headers: {\n      'Authorization': 'Bearer pk_live_...',\n    },\n  },\n);\nconst domain = await response.json();\n"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    'https://api.postkit.eu/v1/domains/dom_abc123/verify',\n    headers={'Authorization': 'Bearer pk_live_...'},\n)\ndomain = response.json()\n"
          }
        ]
      }
    },
    "/api-keys": {
      "post": {
        "operationId": "createApiKey",
        "tags": [
          "API Keys"
        ],
        "summary": "Create an API key",
        "description": "Creates a new API key. The full key is only returned once in this response.\nStore it securely as it cannot be retrieved again.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyRequest"
              },
              "example": {
                "name": "Production Backend",
                "permission": "sending_access",
                "domain_id": "dom_k3j2h1g0"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "API key created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyCreated"
                },
                "example": {
                  "id": "key_m4n5o6p7",
                  "name": "Production Backend",
                  "key": "pk_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
                  "permission": "sending_access",
                  "domain_id": "dom_k3j2h1g0",
                  "created_at": "2026-03-12T10:00:00Z"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listApiKeys",
        "tags": [
          "API Keys"
        ],
        "summary": "List API keys",
        "responses": {
          "200": {
            "description": "List of API keys",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ApiKey"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api-keys/{key_id}": {
      "delete": {
        "operationId": "deleteApiKey",
        "tags": [
          "API Keys"
        ],
        "summary": "Delete an API key",
        "description": "Immediately invalidates the API key. This action cannot be undone.",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "API key deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/webhooks": {
      "post": {
        "operationId": "createWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Create a webhook",
        "description": "Register a webhook endpoint to receive real-time event notifications.\nA signing secret is generated automatically for HMAC-SHA256 verification.\nA test event will be sent to verify the endpoint.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              },
              "example": {
                "url": "https://api.acme.eu/webhooks/postkit",
                "events": [
                  "email.sent",
                  "email.delivered",
                  "email.bounced",
                  "email.opened",
                  "email.clicked",
                  "email.complained",
                  "email.received"
                ],
                "active": true
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "cURL",
            "source": "curl -X POST https://api.postkit.eu/v1/webhooks \\\n  -H \"Authorization: Bearer pk_live_...\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://example.com/webhooks/postkit\",\n    \"events\": [\"email.delivered\", \"email.bounced\", \"email.complained\"]\n  }'\n"
          },
          {
            "lang": "TypeScript",
            "label": "TypeScript",
            "source": "const response = await fetch('https://api.postkit.eu/v1/webhooks', {\n  method: 'POST',\n  headers: {\n    'Authorization': 'Bearer pk_live_...',\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    url: 'https://example.com/webhooks/postkit',\n    events: ['email.delivered', 'email.bounced', 'email.complained'],\n  }),\n});\nconst webhook = await response.json();\n"
          },
          {
            "lang": "Python",
            "label": "Python",
            "source": "import requests\n\nresponse = requests.post(\n    'https://api.postkit.eu/v1/webhooks',\n    headers={'Authorization': 'Bearer pk_live_...'},\n    json={\n        'url': 'https://example.com/webhooks/postkit',\n        'events': ['email.delivered', 'email.bounced', 'email.complained'],\n    },\n)\nwebhook = response.json()\n"
          }
        ]
      },
      "get": {
        "operationId": "listWebhooks",
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhooks",
        "responses": {
          "200": {
            "description": "List of webhooks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/{webhook_id}": {
      "get": {
        "operationId": "retrieveWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Retrieve a webhook",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookId"
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Update a webhook",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/WebhookEventType"
                    }
                  },
                  "active": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete a webhook",
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookId"
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/templates": {
      "post": {
        "operationId": "createTemplate",
        "tags": [
          "Templates"
        ],
        "summary": "Create a template",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTemplateRequest"
              },
              "example": {
                "name": "Order Confirmation",
                "subject": "Your order {{order_id}} has been confirmed",
                "html": "<h1>Hi {{customer_name}},</h1><p>Your order {{order_id}} is confirmed. Total: {{total}}</p>",
                "text": "Hi {{customer_name}}, Your order {{order_id}} is confirmed. Total: {{total}}",
                "engine": "handlebars",
                "variables": [
                  {
                    "name": "order_id",
                    "type": "string",
                    "required": true
                  },
                  {
                    "name": "customer_name",
                    "type": "string",
                    "required": true
                  },
                  {
                    "name": "total",
                    "type": "string",
                    "required": true
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template created (as draft)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listTemplates",
        "tags": [
          "Templates"
        ],
        "summary": "List templates",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          }
        ],
        "responses": {
          "200": {
            "description": "List of templates",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Template"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/templates/{template_id}": {
      "get": {
        "operationId": "retrieveTemplate",
        "tags": [
          "Templates"
        ],
        "summary": "Retrieve a template",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "Template details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateTemplate",
        "tags": [
          "Templates"
        ],
        "summary": "Update a template",
        "description": "Updates create a new draft version. The currently published version remains active.",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "subject": {
                    "type": "string"
                  },
                  "html": {
                    "type": "string"
                  },
                  "text": {
                    "type": "string"
                  },
                  "variables": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TemplateVariable"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Template updated (new draft version)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteTemplate",
        "tags": [
          "Templates"
        ],
        "summary": "Delete a template",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "Template deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/templates/{template_id}/publish": {
      "post": {
        "operationId": "publishTemplate",
        "tags": [
          "Templates"
        ],
        "summary": "Publish a template",
        "description": "Promotes the current draft to the published version. Only published templates can be used when sending emails.",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "Template published",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          }
        }
      }
    },
    "/templates/{template_id}/duplicate": {
      "post": {
        "operationId": "duplicateTemplate",
        "tags": [
          "Templates"
        ],
        "summary": "Duplicate a template",
        "description": "Creates a copy of the template as a new draft.",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name for the duplicated template. Defaults to \"Copy of {original name}\"."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Template duplicated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Template"
                }
              }
            }
          }
        }
      }
    },
    "/templates/render": {
      "post": {
        "operationId": "renderTemplate",
        "tags": [
          "Templates"
        ],
        "summary": "Preview-render a template",
        "description": "Renders a published template with the provided variables and returns the resulting HTML.\nUseful for preview and testing purposes. Does not send any email.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "template_id",
                  "template_data"
                ],
                "properties": {
                  "template_id": {
                    "type": "string"
                  },
                  "template_data": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Rendered template",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "html": {
                      "type": "string",
                      "description": "Rendered HTML output"
                    },
                    "text": {
                      "type": "string",
                      "description": "Rendered plain-text output"
                    },
                    "subject": {
                      "type": "string",
                      "description": "Rendered subject line"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/suppressions": {
      "get": {
        "operationId": "listSuppressions",
        "tags": [
          "Suppressions"
        ],
        "summary": "List suppressed addresses",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "name": "reason",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "hard_bounce",
                "complaint",
                "manual"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of suppressions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Suppression"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createSuppression",
        "tags": [
          "Suppressions"
        ],
        "summary": "Add an address to the suppression list",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "reason": {
                    "type": "string",
                    "enum": [
                      "manual"
                    ],
                    "default": "manual"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Suppression created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Suppression"
                }
              }
            }
          }
        }
      }
    },
    "/suppressions/{suppression_id}": {
      "delete": {
        "operationId": "deleteSuppression",
        "tags": [
          "Suppressions"
        ],
        "summary": "Remove an address from the suppression list",
        "description": "Removes a suppression entry, allowing future emails to this address.\nUse with caution: sending to previously bounced addresses may harm your domain reputation.\n",
        "parameters": [
          {
            "name": "suppression_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Suppression removed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/contacts": {
      "post": {
        "operationId": "createContact",
        "tags": [
          "Contacts"
        ],
        "summary": "Create a contact",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactRequest"
              },
              "example": {
                "email": "max@example.com",
                "first_name": "Max",
                "last_name": "Mustermann",
                "unsubscribed": false,
                "properties": {
                  "country": "DE",
                  "company": "Acme GmbH"
                },
                "consent_given_at": "2026-03-01T12:00:00Z"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Contact created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          },
          "409": {
            "description": "Contact with this email already exists",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listContacts",
        "tags": [
          "Contacts"
        ],
        "summary": "List contacts",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "name": "audience_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "unsubscribed",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "email",
            "in": "query",
            "schema": {
              "type": "string",
              "description": "Exact match on email address"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of contacts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Contact"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/contacts/{contact_id}": {
      "get": {
        "operationId": "retrieveContact",
        "tags": [
          "Contacts"
        ],
        "summary": "Retrieve a contact",
        "parameters": [
          {
            "$ref": "#/components/parameters/ContactId"
          }
        ],
        "responses": {
          "200": {
            "description": "Contact details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateContact",
        "tags": [
          "Contacts"
        ],
        "summary": "Update a contact",
        "parameters": [
          {
            "$ref": "#/components/parameters/ContactId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "first_name": {
                    "type": "string"
                  },
                  "last_name": {
                    "type": "string"
                  },
                  "unsubscribed": {
                    "type": "boolean"
                  },
                  "properties": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Contact"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteContact",
        "tags": [
          "Contacts"
        ],
        "summary": "Delete a contact",
        "description": "Permanently deletes all personal data for this contact (GDPR Art. 17).\nActivity logs are anonymized but retained for analytics.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/ContactId"
          }
        ],
        "responses": {
          "200": {
            "description": "Contact deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/contacts/{contact_id}/topics": {
      "get": {
        "operationId": "getContactTopics",
        "tags": [
          "Contacts"
        ],
        "summary": "Get subscription topics for a contact",
        "parameters": [
          {
            "$ref": "#/components/parameters/ContactId"
          }
        ],
        "responses": {
          "200": {
            "description": "Topic subscriptions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "topic_id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "subscribed": {
                            "type": "boolean"
                          },
                          "updated_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateContactTopics",
        "tags": [
          "Contacts"
        ],
        "summary": "Update topic subscriptions for a contact",
        "parameters": [
          {
            "$ref": "#/components/parameters/ContactId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "topics"
                ],
                "properties": {
                  "topics": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "topic_id",
                        "subscribed"
                      ],
                      "properties": {
                        "topic_id": {
                          "type": "string"
                        },
                        "subscribed": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Topics updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "topic_id": {
                            "type": "string"
                          },
                          "subscribed": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/audiences": {
      "post": {
        "operationId": "createAudience",
        "tags": [
          "Audiences"
        ],
        "summary": "Create an audience",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Audience created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Audience"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listAudiences",
        "tags": [
          "Audiences"
        ],
        "summary": "List audiences",
        "responses": {
          "200": {
            "description": "List of audiences",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Audience"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/audiences/{audience_id}": {
      "get": {
        "operationId": "retrieveAudience",
        "tags": [
          "Audiences"
        ],
        "summary": "Retrieve an audience",
        "parameters": [
          {
            "$ref": "#/components/parameters/AudienceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Audience details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Audience"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAudience",
        "tags": [
          "Audiences"
        ],
        "summary": "Delete an audience",
        "description": "Deletes the audience. Contacts that belong to it are not deleted.",
        "parameters": [
          {
            "$ref": "#/components/parameters/AudienceId"
          }
        ],
        "responses": {
          "200": {
            "description": "Audience deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/topics": {
      "post": {
        "operationId": "createTopic",
        "tags": [
          "Topics"
        ],
        "summary": "Create a topic",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Topic created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Topic"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listTopics",
        "tags": [
          "Topics"
        ],
        "summary": "List topics",
        "responses": {
          "200": {
            "description": "List of topics",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Topic"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/topics/{topic_id}": {
      "get": {
        "operationId": "retrieveTopic",
        "tags": [
          "Topics"
        ],
        "summary": "Retrieve a topic",
        "parameters": [
          {
            "$ref": "#/components/parameters/TopicId"
          }
        ],
        "responses": {
          "200": {
            "description": "Topic details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Topic"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateTopic",
        "tags": [
          "Topics"
        ],
        "summary": "Update a topic",
        "parameters": [
          {
            "$ref": "#/components/parameters/TopicId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Topic updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Topic"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteTopic",
        "tags": [
          "Topics"
        ],
        "summary": "Delete a topic",
        "parameters": [
          {
            "$ref": "#/components/parameters/TopicId"
          }
        ],
        "responses": {
          "200": {
            "description": "Topic deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts": {
      "post": {
        "operationId": "createBroadcast",
        "tags": [
          "Broadcasts"
        ],
        "summary": "Create a broadcast",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBroadcastRequest"
              },
              "example": {
                "name": "March Newsletter",
                "from": "Newsletter <news@acme.eu>",
                "subject": "What's new in March",
                "template_id": "tmpl_abc123",
                "template_data": {
                  "month": "March"
                },
                "audience_id": "aud_x1y2z3",
                "topic_id": "top_a1b2c3",
                "send_at": "2026-03-15T09:00:00Z"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Broadcast created (as draft)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Broadcast"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listBroadcasts",
        "tags": [
          "Broadcasts"
        ],
        "summary": "List broadcasts",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/StartingAfter"
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "draft",
                "scheduled",
                "sending",
                "sent",
                "canceled"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of broadcasts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Broadcast"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts/{broadcast_id}": {
      "get": {
        "operationId": "retrieveBroadcast",
        "tags": [
          "Broadcasts"
        ],
        "summary": "Retrieve a broadcast",
        "parameters": [
          {
            "$ref": "#/components/parameters/BroadcastId"
          }
        ],
        "responses": {
          "200": {
            "description": "Broadcast details with analytics",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Broadcast"
                }
              }
            }
          }
        }
      },
      "patch": {
        "operationId": "updateBroadcast",
        "tags": [
          "Broadcasts"
        ],
        "summary": "Update a broadcast",
        "description": "Only broadcasts with status `draft` or `scheduled` can be updated.",
        "parameters": [
          {
            "$ref": "#/components/parameters/BroadcastId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "from": {
                    "type": "string"
                  },
                  "subject": {
                    "type": "string"
                  },
                  "template_id": {
                    "type": "string"
                  },
                  "template_data": {
                    "type": "object"
                  },
                  "audience_id": {
                    "type": "string"
                  },
                  "topic_id": {
                    "type": "string"
                  },
                  "send_at": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Broadcast updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Broadcast"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteBroadcast",
        "tags": [
          "Broadcasts"
        ],
        "summary": "Delete a broadcast",
        "parameters": [
          {
            "$ref": "#/components/parameters/BroadcastId"
          }
        ],
        "responses": {
          "200": {
            "description": "Broadcast deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "deleted": {
                      "type": "boolean",
                      "example": true
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/broadcasts/{broadcast_id}/send": {
      "post": {
        "operationId": "sendBroadcast",
        "tags": [
          "Broadcasts"
        ],
        "summary": "Send a broadcast",
        "description": "Triggers immediate sending of a draft broadcast, or confirms a scheduled broadcast.\nResolves the audience, checks suppression and unsubscribe status per contact,\nand enqueues individual emails for delivery.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/BroadcastId"
          }
        ],
        "responses": {
          "200": {
            "description": "Broadcast sending initiated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Broadcast"
                }
              }
            }
          },
          "409": {
            "description": "Broadcast cannot be sent (already sent or canceled)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "pk_live_* or pk_test_*",
        "description": "API Key authentication. Keys prefixed with `pk_live_` operate in production mode.\nKeys prefixed with `pk_test_` operate in sandbox mode (no emails delivered).\n"
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "schema": {
          "type": "string",
          "maxLength": 255
        },
        "description": "Unique key to prevent duplicate processing. Cached for 48 hours."
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 25
        },
        "description": "Number of items to return per page."
      },
      "StartingAfter": {
        "name": "starting_after",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Cursor for forward pagination. Use the `id` of the last item from the previous page."
      },
      "EndingBefore": {
        "name": "ending_before",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Cursor for backward pagination."
      },
      "EmailId": {
        "name": "email_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "Prefixed ID (em_ for sent, in_ for received)"
      },
      "AttachmentId": {
        "name": "attachment_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "DomainId": {
        "name": "domain_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "WebhookId": {
        "name": "webhook_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "TemplateId": {
        "name": "template_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "ContactId": {
        "name": "contact_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "AudienceId": {
        "name": "audience_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "TopicId": {
        "name": "topic_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "BroadcastId": {
        "name": "broadcast_id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "invalid_request",
                "message": "The 'to' field must contain at least one recipient.",
                "code": "missing_required_field"
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "authentication_error",
                "message": "Invalid API key provided.",
                "code": "invalid_api_key"
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "not_found",
                "message": "The requested resource does not exist.",
                "code": "resource_not_found"
              }
            }
          }
        }
      },
      "ValidationError": {
        "description": "Validation failed",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "headers": {
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "Requests allowed per second"
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            },
            "description": "Requests remaining in current window"
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "integer"
            },
            "description": "Unix timestamp when the rate limit resets"
          },
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds to wait before retrying"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "error": {
                "type": "rate_limit_error",
                "message": "Rate limit exceeded. Retry after 1 second.",
                "code": "rate_limit_exceeded"
              }
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "type",
              "message"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "authentication_error",
                  "not_found",
                  "rate_limit_error",
                  "conflict",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "description": "Machine-readable error code for programmatic handling"
              }
            }
          }
        }
      },
      "SendEmailRequest": {
        "type": "object",
        "required": [
          "from",
          "to"
        ],
        "properties": {
          "from": {
            "type": "string",
            "description": "Sender address. Format: \"Name <email@domain.com>\" or \"email@domain.com\"",
            "example": "Acme <noreply@acme.eu>"
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            },
            "minItems": 1,
            "maxItems": 50,
            "description": "Recipient addresses (max 50)"
          },
          "subject": {
            "type": "string",
            "maxLength": 998,
            "description": "Required unless template_id provides a default subject"
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            }
          },
          "bcc": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            }
          },
          "reply_to": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Reply-to addresses"
          },
          "html": {
            "type": "string",
            "description": "HTML body. Mutually exclusive with template_id."
          },
          "text": {
            "type": "string",
            "description": "Plain text body. Auto-generated from HTML if omitted."
          },
          "template_id": {
            "type": "string",
            "description": "ID of a published template. Mutually exclusive with html/text."
          },
          "template_data": {
            "type": "object",
            "additionalProperties": true,
            "description": "Variables for template rendering"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 256,
              "pattern": "^[a-zA-Z0-9_-]+$"
            },
            "maxItems": 5,
            "description": "Tags for categorization and filtering"
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "filename",
                "content"
              ],
              "properties": {
                "filename": {
                  "type": "string"
                },
                "content": {
                  "type": "string",
                  "description": "Base64-encoded file content"
                },
                "content_type": {
                  "type": "string",
                  "default": "application/octet-stream"
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Remote URL to fetch the file from (alternative to content)"
                }
              }
            },
            "maxItems": 10
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Custom email headers (X-* headers only)"
          },
          "send_at": {
            "type": "string",
            "format": "date-time",
            "description": "Schedule delivery for a future time (ISO 8601). Max 72 hours in the future."
          }
        }
      },
      "SendEmailResponse": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique email ID (prefixed with em_)",
            "example": "em_a1b2c3d4e5"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "scheduled"
            ]
          }
        }
      },
      "Email": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "bcc": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "reply_to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "subject": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "scheduled",
              "sending",
              "sent",
              "delivered",
              "bounced",
              "complained",
              "canceled"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "template_id": {
            "type": "string",
            "nullable": true
          },
          "send_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "delivered_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "opened_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "First open timestamp"
          },
          "clicked_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "First click timestamp"
          },
          "bounce_type": {
            "type": "string",
            "enum": [
              "hard",
              "soft"
            ],
            "nullable": true
          },
          "bounce_message": {
            "type": "string",
            "nullable": true
          },
          "open_count": {
            "type": "integer"
          },
          "click_count": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "EmailList": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Email"
            }
          },
          "has_more": {
            "type": "boolean"
          }
        }
      },
      "ReceivedEmail": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Prefixed with in_"
          },
          "from": {
            "type": "object",
            "properties": {
              "email": {
                "type": "string"
              },
              "name": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "to": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "email": {
                  "type": "string"
                },
                "name": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          },
          "cc": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "email": {
                  "type": "string"
                },
                "name": {
                  "type": "string",
                  "nullable": true
                }
              }
            }
          },
          "subject": {
            "type": "string"
          },
          "text_body": {
            "type": "string",
            "nullable": true
          },
          "html_body": {
            "type": "string",
            "nullable": true
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Selected email headers (message-id, date, references, in-reply-to)"
          },
          "spam_score": {
            "type": "number",
            "format": "float",
            "description": "SpamAssassin score (lower is better)"
          },
          "is_spam": {
            "type": "boolean"
          },
          "attachment_count": {
            "type": "integer"
          },
          "domain": {
            "type": "string",
            "description": "Receiving domain"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ReceivedEmailList": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReceivedEmail"
            }
          },
          "has_more": {
            "type": "boolean"
          }
        }
      },
      "Attachment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "content_type": {
            "type": "string"
          },
          "size": {
            "type": "integer",
            "description": "Size in bytes"
          }
        }
      },
      "AttachmentDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Attachment"
          },
          {
            "type": "object",
            "properties": {
              "download_url": {
                "type": "string",
                "format": "uri",
                "description": "Pre-signed URL valid for 1 hour"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          }
        ]
      },
      "CreateDomainRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Domain name (e.g. \"acme.eu\")"
          },
          "region": {
            "type": "string",
            "enum": [
              "eu"
            ],
            "default": "eu",
            "description": "Data residency region. Currently EU only."
          },
          "open_tracking": {
            "type": "boolean",
            "default": true
          },
          "click_tracking": {
            "type": "boolean",
            "default": true
          },
          "inbound_enabled": {
            "type": "boolean",
            "default": false,
            "description": "Enable inbound email processing for this domain"
          },
          "impressum": {
            "$ref": "#/components/schemas/Impressum"
          }
        }
      },
      "Impressum": {
        "type": "object",
        "description": "Legal notice (required by German/Austrian/Swiss law for commercial emails)",
        "properties": {
          "company_name": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "contact_email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          },
          "registry_info": {
            "type": "string",
            "description": "e.g. HRB 12345, Amtsgericht Berlin"
          }
        }
      },
      "Domain": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "verified",
              "failed"
            ]
          },
          "region": {
            "type": "string"
          },
          "open_tracking": {
            "type": "boolean"
          },
          "click_tracking": {
            "type": "boolean"
          },
          "inbound_enabled": {
            "type": "boolean"
          },
          "impressum": {
            "$ref": "#/components/schemas/Impressum"
          },
          "dns_records": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DnsRecord"
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DnsRecord": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "TXT",
              "CNAME",
              "MX"
            ]
          },
          "name": {
            "type": "string",
            "description": "DNS record hostname"
          },
          "value": {
            "type": "string",
            "description": "DNS record value"
          },
          "purpose": {
            "type": "string",
            "enum": [
              "dkim",
              "spf",
              "dmarc",
              "return_path",
              "tracking",
              "mx_inbound"
            ]
          },
          "priority": {
            "type": "integer",
            "nullable": true,
            "description": "MX priority (only for MX records)"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "verified",
              "failed"
            ]
          }
        }
      },
      "CreateApiKeyRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "permission": {
            "type": "string",
            "enum": [
              "full_access",
              "sending_access"
            ],
            "default": "full_access",
            "description": "- `full_access`: All API operations\n- `sending_access`: Only send emails (POST /emails, POST /emails/batch)\n"
          },
          "domain_id": {
            "type": "string",
            "nullable": true,
            "description": "Restrict this key to a specific verified domain"
          }
        }
      },
      "ApiKeyCreated": {
        "type": "object",
        "description": "Only returned on creation. The full key is never shown again.",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "key": {
            "type": "string",
            "description": "Full API key (pk_live_... or pk_test_...). Store securely."
          },
          "permission": {
            "type": "string"
          },
          "domain_id": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "description": "API key summary (key itself is never returned after creation)",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "key_prefix": {
            "type": "string",
            "description": "First 12 characters of the key for identification (e.g. pk_live_a1b2)"
          },
          "permission": {
            "type": "string",
            "enum": [
              "full_access",
              "sending_access"
            ]
          },
          "domain_id": {
            "type": "string",
            "nullable": true
          },
          "last_used_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "WebhookEventType": {
        "type": "string",
        "enum": [
          "email.sent",
          "email.delivered",
          "email.delivery_delayed",
          "email.bounced",
          "email.complained",
          "email.opened",
          "email.clicked",
          "email.canceled",
          "email.received",
          "contact.created",
          "contact.updated",
          "contact.deleted",
          "contact.unsubscribed",
          "domain.verified",
          "domain.dns_changed"
        ]
      },
      "CreateWebhookRequest": {
        "type": "object",
        "required": [
          "url",
          "events"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS endpoint URL"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            },
            "minItems": 1
          },
          "active": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventType"
            }
          },
          "active": {
            "type": "boolean"
          },
          "signing_secret": {
            "type": "string",
            "description": "HMAC-SHA256 signing secret (shown masked after creation: whsec_****)"
          },
          "delivery_rate": {
            "type": "number",
            "format": "float",
            "description": "Successful delivery percentage (last 24 hours)"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TemplateVariable": {
        "type": "object",
        "required": [
          "name",
          "type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
            "maxLength": 50
          },
          "type": {
            "type": "string",
            "enum": [
              "string",
              "number",
              "boolean",
              "date",
              "url"
            ]
          },
          "required": {
            "type": "boolean",
            "default": false
          },
          "default_value": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "CreateTemplateRequest": {
        "type": "object",
        "required": [
          "name",
          "subject",
          "html"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "subject": {
            "type": "string",
            "maxLength": 998,
            "description": "Supports variable interpolation (e.g. \"Order {{order_id}} confirmed\")"
          },
          "html": {
            "type": "string",
            "description": "HTML or MJML content with Handlebars variables"
          },
          "text": {
            "type": "string",
            "nullable": true,
            "description": "Plain text version. Auto-generated from HTML if omitted."
          },
          "engine": {
            "type": "string",
            "enum": [
              "handlebars",
              "plain"
            ],
            "default": "handlebars",
            "description": "Template rendering engine"
          },
          "variables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateVariable"
            },
            "description": "Variable schema for validation and documentation"
          }
        }
      },
      "Template": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "html": {
            "type": "string"
          },
          "text": {
            "type": "string",
            "nullable": true
          },
          "engine": {
            "type": "string"
          },
          "variables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateVariable"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "published"
            ]
          },
          "version": {
            "type": "integer",
            "description": "Current version number"
          },
          "published_version": {
            "type": "integer",
            "nullable": true,
            "description": "Last published version number"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Suppression": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "reason": {
            "type": "string",
            "enum": [
              "hard_bounce",
              "complaint",
              "manual"
            ]
          },
          "detail": {
            "type": "string",
            "nullable": true,
            "description": "Bounce message or complaint feedback"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateContactRequest": {
        "type": "object",
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "first_name": {
            "type": "string",
            "maxLength": 255
          },
          "last_name": {
            "type": "string",
            "maxLength": 255
          },
          "unsubscribed": {
            "type": "boolean",
            "default": false
          },
          "audience_id": {
            "type": "string",
            "nullable": true,
            "description": "Add contact to this audience on creation"
          },
          "properties": {
            "type": "object",
            "additionalProperties": true,
            "description": "Custom key-value properties"
          },
          "consent_given_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "GDPR consent timestamp"
          }
        }
      },
      "Contact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "first_name": {
            "type": "string",
            "nullable": true
          },
          "last_name": {
            "type": "string",
            "nullable": true
          },
          "unsubscribed": {
            "type": "boolean"
          },
          "properties": {
            "type": "object",
            "additionalProperties": true
          },
          "consent_given_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "audiences": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "IDs of audiences this contact belongs to"
          },
          "activity": {
            "type": "object",
            "description": "Summary of email activity",
            "properties": {
              "emails_sent": {
                "type": "integer"
              },
              "last_sent_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "last_opened_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              },
              "last_clicked_at": {
                "type": "string",
                "format": "date-time",
                "nullable": true
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Audience": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "contact_count": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Topic": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "subscriber_count": {
            "type": "integer"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateBroadcastRequest": {
        "type": "object",
        "required": [
          "name",
          "from",
          "audience_id"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "from": {
            "type": "string"
          },
          "subject": {
            "type": "string",
            "description": "Required unless template provides a default"
          },
          "html": {
            "type": "string",
            "description": "Mutually exclusive with template_id"
          },
          "text": {
            "type": "string"
          },
          "template_id": {
            "type": "string",
            "description": "Mutually exclusive with html/text"
          },
          "template_data": {
            "type": "object",
            "additionalProperties": true,
            "description": "Global template variables (contact properties are merged automatically)"
          },
          "audience_id": {
            "type": "string"
          },
          "topic_id": {
            "type": "string",
            "nullable": true,
            "description": "Only send to contacts subscribed to this topic"
          },
          "send_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Schedule delivery (omit for draft)"
          },
          "reply_to": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 5
          }
        }
      },
      "Broadcast": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "subject": {
            "type": "string"
          },
          "template_id": {
            "type": "string",
            "nullable": true
          },
          "audience_id": {
            "type": "string"
          },
          "topic_id": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "scheduled",
              "sending",
              "sent",
              "canceled"
            ]
          },
          "send_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "analytics": {
            "type": "object",
            "nullable": true,
            "description": "Only populated after sending",
            "properties": {
              "total_recipients": {
                "type": "integer"
              },
              "sent": {
                "type": "integer"
              },
              "delivered": {
                "type": "integer"
              },
              "bounced": {
                "type": "integer"
              },
              "opened": {
                "type": "integer"
              },
              "clicked": {
                "type": "integer"
              },
              "unsubscribed": {
                "type": "integer"
              },
              "open_rate": {
                "type": "number",
                "format": "float"
              },
              "click_rate": {
                "type": "number",
                "format": "float"
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    }
  }
}