{
  "openapi": "3.1.0",
  "info": {
    "title": "Sendora API",
    "version": "1",
    "description": "Transactional email delivery. Every request carries an API key as a bearer token: a server key (sk_) for everything inside one server, an account key (ak_) for what belongs to the account; a key of the wrong kind answers 403 wrong_token_kind. Every error answers a JSON body with an error code and a message."
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "A server key (sk_…): created with its server, in the dashboard, under /v1/servers/{id}/tokens with an account key, or under /v1/tokens with a key of the same server."
      },
      "accountToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "An account key (ak_…), created by an administrator in the dashboard under Account › API keys; it manages the account’s servers, their keys and its sending domains, erases a person’s data, and never sends."
      }
    },
    "schemas": {}
  },
  "paths": {
    "/v1/email": {
      "post": {
        "summary": "Send one message",
        "tags": [
          "Sending"
        ],
        "description": "Accepts one message for delivery and answers at once with its id. Delivery, deferral, bounce and complaint arrive later as events on the message and as webhooks. With an Idempotency-Key, a retry within 24 hours gets the first answer again, marked by the Idempotent-Replayed header, and sends nothing twice.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "from": {
                    "description": "The sender. Its domain must be a verified sending domain of the server.",
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "email",
                        "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "email": {
                            "type": "string",
                            "format": "email",
                            "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                          },
                          "name": {
                            "default": null,
                            "description": "A display name of up to 200 characters.",
                            "anyOf": [
                              {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "email"
                        ]
                      }
                    ]
                  },
                  "streamId": {
                    "description": "The stream of this server the message goes on; the default transactional stream when absent.",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "to": {
                    "minItems": 1,
                    "type": "array",
                    "items": {
                      "description": "An address as a plain string, or an object with the address and a display name.",
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "email",
                          "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "email": {
                              "type": "string",
                              "format": "email",
                              "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                            },
                            "name": {
                              "default": null,
                              "description": "A display name of up to 200 characters.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "email"
                          ]
                        }
                      ]
                    },
                    "description": "Recipients; at most 50 across to, cc and bcc."
                  },
                  "cc": {
                    "description": "Copied recipients, shown in the message.",
                    "type": "array",
                    "items": {
                      "description": "An address as a plain string, or an object with the address and a display name.",
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "email",
                          "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "email": {
                              "type": "string",
                              "format": "email",
                              "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                            },
                            "name": {
                              "default": null,
                              "description": "A display name of up to 200 characters.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "email"
                          ]
                        }
                      ]
                    }
                  },
                  "bcc": {
                    "description": "Blind-copied recipients.",
                    "type": "array",
                    "items": {
                      "description": "An address as a plain string, or an object with the address and a display name.",
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "email",
                          "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "email": {
                              "type": "string",
                              "format": "email",
                              "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                            },
                            "name": {
                              "default": null,
                              "description": "A display name of up to 200 characters.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "email"
                          ]
                        }
                      ]
                    }
                  },
                  "subject": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 998,
                    "description": "The subject line."
                  },
                  "text": {
                    "description": "The plain-text part. At least one of text and html is required.",
                    "type": "string",
                    "minLength": 1
                  },
                  "html": {
                    "description": "The HTML part.",
                    "type": "string",
                    "minLength": 1
                  },
                  "headers": {
                    "default": {},
                    "description": "Custom headers by name, at most 20. Sendora writes these itself, so a message may not set them: From, Sender, To, Cc, Bcc, Subject, Date, Message-ID, MIME-Version, Return-Path, Received, Delivered-To, DKIM-Signature, DomainKey-Signature, Authentication-Results, Received-SPF, and any name that starts with Content-, Resent-, ARC- or X-Kumo.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string",
                      "pattern": "^[^\\p{Cc}]{1,998}$"
                    }
                  },
                  "attachments": {
                    "description": "At most 20. A message with its attachments encoded may be at most 10 MB.",
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "pattern": "^[^\\p{Cc}/\\\\]{1,255}$"
                        },
                        "content": {
                          "type": "string",
                          "format": "byte",
                          "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$"
                        },
                        "contentType": {
                          "type": "string",
                          "pattern": "^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$"
                        },
                        "contentId": {
                          "default": null,
                          "anyOf": [
                            {
                              "type": "string",
                              "pattern": "^[^\\s<>\\p{Cc}]{1,255}$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "name",
                        "content"
                      ]
                    }
                  },
                  "tag": {
                    "default": null,
                    "description": "A label of up to 100 characters, returned with the message and its events.",
                    "anyOf": [
                      {
                        "type": "string",
                        "pattern": "^[^\\p{Cc}]{1,100}$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "metadata": {
                    "default": {},
                    "description": "Up to 20 key-value pairs of your own, returned with the message and its events.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string",
                      "pattern": "^[^\\p{Cc}]{0,500}$"
                    }
                  }
                },
                "required": [
                  "from",
                  "to",
                  "subject"
                ]
              },
              "examples": {
                "example": {
                  "summary": "An invoice with a PDF attached",
                  "value": {
                    "from": {
                      "email": "no-reply@example.se",
                      "name": "Example AB"
                    },
                    "to": [
                      "anna@example.com"
                    ],
                    "subject": "Your invoice for September",
                    "text": "Hi Anna, your invoice is attached.",
                    "attachments": [
                      {
                        "name": "invoice.pdf",
                        "content": "JVBERi0xLjcK",
                        "contentType": "application/pdf"
                      }
                    ],
                    "tag": "invoice",
                    "metadata": {
                      "invoiceId": "2026-0912"
                    }
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[^\\p{Cc}]{1,255}$"
            },
            "in": "header",
            "name": "idempotency-key",
            "required": false,
            "description": "Any text of 1 to 255 printable characters that identifies this request; the same key with a different body is refused."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Accepted for delivery.",
            "headers": {
              "Idempotent-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                "description": "true when this is the first answer again, to a request sent before under the same Idempotency-Key; absent otherwise."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "messageId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The id the message log, the events and the webhooks refer to."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "accepted"
                      ]
                    },
                    "submittedAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                      "description": "When the message was accepted."
                    },
                    "test": {
                      "type": "boolean",
                      "description": "True when the server is a test server: the message goes through everything but delivery, and nobody receives it."
                    }
                  },
                  "required": [
                    "messageId",
                    "status",
                    "submittedAt",
                    "test"
                  ],
                  "additionalProperties": false,
                  "description": "Accepted for delivery."
                },
                "examples": {
                  "example": {
                    "summary": "Accepted",
                    "value": {
                      "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                      "status": "accepted",
                      "submittedAt": "2026-09-15T12:00:00.000Z",
                      "test": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "402": {
            "description": "The account has no active subscription.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "payment_required"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The account has no active subscription."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind, or the account is paused, closed or not yet approved for a live server's sends.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "wrong_token_kind"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "account_paused"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The account is paused by Sendora."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "account_not_active"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The account is closed, or not yet approved for a live server's sends or an inbound stream."
                    }
                  ],
                  "description": "The key is of the other kind, or the account is paused, closed or not yet approved for a live server's sends."
                }
              }
            }
          },
          "413": {
            "description": "The body exceeds 10 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "request_too_large"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body exceeds 10 MB."
                }
              }
            }
          },
          "422": {
            "description": "The message cannot be sent as it stands; the code says why.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "from_domain_not_verified"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The From domain is not a verified sending domain of this server."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_not_found"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The streamId names no stream of this server."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_archived"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The stream is archived and takes no new messages."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_paused"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "Sendora has paused the stream after complaints; it takes no messages until support has resumed it."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_not_sendable"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "An inbound stream receives mail; it takes no messages and has no suppression list. Name a transactional or broadcast stream."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "unsubscribe_placeholder_missing"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "A message on a broadcast stream must carry {{ unsubscribe_url }} in every part it has."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "list_unsubscribe_reserved"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "On a broadcast stream Sendora writes the List-Unsubscribe pair itself, so a message may not carry one."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "recipient_suppressed"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "streamId": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                          "description": "The stream whose suppression list refused the send."
                        },
                        "suppressed": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "address": {
                                "type": "string"
                              },
                              "reason": {
                                "type": "string",
                                "enum": [
                                  "hard_bounce",
                                  "spam_complaint",
                                  "manual",
                                  "unsubscribe"
                                ]
                              }
                            },
                            "required": [
                              "address",
                              "reason"
                            ],
                            "additionalProperties": false
                          },
                          "description": "Each refused address, lower-cased, with the reason it is on the list."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "streamId",
                        "suppressed"
                      ],
                      "additionalProperties": false,
                      "description": "One or more recipients are on the suppression list of the stream.",
                      "examples": [
                        {
                          "error": "recipient_suppressed",
                          "message": "One or more recipients are on the suppression list of this stream; suppressed says which and why.",
                          "streamId": "3d1a2b4c-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "suppressed": [
                            {
                              "address": "anna@example.com",
                              "reason": "hard_bounce"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "test_address_on_live_server"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "addresses": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "The recipients at simulator.sendora.se, each once."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "addresses"
                      ],
                      "additionalProperties": false,
                      "description": "Addresses at simulator.sendora.se act out an outcome on a test server; a live server never sends to them.",
                      "examples": [
                        {
                          "error": "test_address_on_live_server",
                          "message": "Addresses at simulator.sendora.se act out an outcome on a test server and are never sent to from a live one. Send them from a test server.",
                          "addresses": [
                            "hardbounce@simulator.sendora.se"
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "idempotency_key_mismatch"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The Idempotency-Key was already used for a different request."
                    }
                  ],
                  "description": "The message cannot be sent as it stands; the code says why."
                }
              }
            }
          },
          "429": {
            "description": "The per-minute limit or the monthly cap is reached.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "With rate_limited, the seconds until a send is accepted; absent with monthly_cap_reached."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "rate_limited"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "scope": {
                          "type": "string",
                          "enum": [
                            "account",
                            "server",
                            "test"
                          ],
                          "description": "Whose limit it is: `account` for the account's, `server` for the server's own, `test` for the cap the account's test servers share."
                        },
                        "limit": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Emails per minute allowed for that scope."
                        },
                        "retryAfter": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Seconds until the next send is accepted; also sent as the Retry-After header."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "scope",
                        "limit",
                        "retryAfter"
                      ],
                      "additionalProperties": false,
                      "description": "More was sent within a minute than the limit allows.",
                      "examples": [
                        {
                          "error": "rate_limited",
                          "message": "This server may send 60 emails per minute. Try again in 12 seconds.",
                          "scope": "server",
                          "limit": 60,
                          "retryAfter": 12
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "monthly_cap_reached"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "scope": {
                          "type": "string",
                          "enum": [
                            "account",
                            "server",
                            "test"
                          ],
                          "description": "Whose limit it is: `account` for the account's, `server` for the server's own, `test` for the cap the account's test servers share."
                        },
                        "cap": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Emails the scope may send in a calendar month, in UTC."
                        },
                        "used": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Emails sent this month, the refused send not counted."
                        },
                        "resetsAt": {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                          "description": "When the month counter resets."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "scope",
                        "cap",
                        "used",
                        "resetsAt"
                      ],
                      "additionalProperties": false,
                      "description": "The monthly cap of the account, the server or the test servers is used up.",
                      "examples": [
                        {
                          "error": "monthly_cap_reached",
                          "message": "This account has used 50000 of 50000 emails this month. The cap resets at 2026-11-01T00:00:00.000Z.",
                          "scope": "account",
                          "cap": 50000,
                          "used": 50000,
                          "resetsAt": "2026-11-01T00:00:00.000Z"
                        }
                      ]
                    }
                  ],
                  "description": "The per-minute limit or the monthly cap is reached."
                }
              }
            }
          },
          "503": {
            "description": "Sending is disabled for everyone for the moment; retry after the seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before trying again."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "sending_disabled"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "Sending is disabled for everyone for the moment; retry after the seconds in Retry-After."
                }
              }
            }
          }
        }
      }
    },
    "/v1/email/batch": {
      "post": {
        "summary": "Send up to 100 messages",
        "tags": [
          "Sending"
        ],
        "description": "Accepts an array of messages and answers one result per message, in order: accepted with its id, or refused with the same error the single send would give. The Idempotency-Key is required. A retry under the same key sends nothing twice: every item accepted before is answered again with replayed set, and only the items that failed are attempted again.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "minItems": 1,
                "maxItems": 100,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "from": {
                      "description": "The sender. Its domain must be a verified sending domain of the server.",
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "email",
                          "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "email": {
                              "type": "string",
                              "format": "email",
                              "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                            },
                            "name": {
                              "default": null,
                              "description": "A display name of up to 200 characters.",
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                {
                                  "type": "null"
                                }
                              ]
                            }
                          },
                          "required": [
                            "email"
                          ]
                        }
                      ]
                    },
                    "streamId": {
                      "description": "The stream of this server the message goes on; the default transactional stream when absent.",
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "to": {
                      "minItems": 1,
                      "type": "array",
                      "items": {
                        "description": "An address as a plain string, or an object with the address and a display name.",
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "email",
                            "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                          },
                          {
                            "type": "object",
                            "properties": {
                              "email": {
                                "type": "string",
                                "format": "email",
                                "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                              },
                              "name": {
                                "default": null,
                                "description": "A display name of up to 200 characters.",
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 200
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "email"
                            ]
                          }
                        ]
                      },
                      "description": "Recipients; at most 50 across to, cc and bcc."
                    },
                    "cc": {
                      "description": "Copied recipients, shown in the message.",
                      "type": "array",
                      "items": {
                        "description": "An address as a plain string, or an object with the address and a display name.",
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "email",
                            "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                          },
                          {
                            "type": "object",
                            "properties": {
                              "email": {
                                "type": "string",
                                "format": "email",
                                "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                              },
                              "name": {
                                "default": null,
                                "description": "A display name of up to 200 characters.",
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 200
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "email"
                            ]
                          }
                        ]
                      }
                    },
                    "bcc": {
                      "description": "Blind-copied recipients.",
                      "type": "array",
                      "items": {
                        "description": "An address as a plain string, or an object with the address and a display name.",
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "email",
                            "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                          },
                          {
                            "type": "object",
                            "properties": {
                              "email": {
                                "type": "string",
                                "format": "email",
                                "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                              },
                              "name": {
                                "default": null,
                                "description": "A display name of up to 200 characters.",
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 200
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "email"
                            ]
                          }
                        ]
                      }
                    },
                    "subject": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 998,
                      "description": "The subject line."
                    },
                    "text": {
                      "description": "The plain-text part. At least one of text and html is required.",
                      "type": "string",
                      "minLength": 1
                    },
                    "html": {
                      "description": "The HTML part.",
                      "type": "string",
                      "minLength": 1
                    },
                    "headers": {
                      "default": {},
                      "description": "Custom headers by name, at most 20. Sendora writes these itself, so a message may not set them: From, Sender, To, Cc, Bcc, Subject, Date, Message-ID, MIME-Version, Return-Path, Received, Delivered-To, DKIM-Signature, DomainKey-Signature, Authentication-Results, Received-SPF, and any name that starts with Content-, Resent-, ARC- or X-Kumo.",
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string",
                        "pattern": "^[^\\p{Cc}]{1,998}$"
                      }
                    },
                    "attachments": {
                      "description": "At most 20. A message with its attachments encoded may be at most 10 MB.",
                      "maxItems": 20,
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string",
                            "pattern": "^[^\\p{Cc}/\\\\]{1,255}$"
                          },
                          "content": {
                            "type": "string",
                            "format": "byte",
                            "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$"
                          },
                          "contentType": {
                            "type": "string",
                            "pattern": "^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$"
                          },
                          "contentId": {
                            "default": null,
                            "anyOf": [
                              {
                                "type": "string",
                                "pattern": "^[^\\s<>\\p{Cc}]{1,255}$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "name",
                          "content"
                        ]
                      }
                    },
                    "tag": {
                      "default": null,
                      "description": "A label of up to 100 characters, returned with the message and its events.",
                      "anyOf": [
                        {
                          "type": "string",
                          "pattern": "^[^\\p{Cc}]{1,100}$"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "metadata": {
                      "default": {},
                      "description": "Up to 20 key-value pairs of your own, returned with the message and its events.",
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string",
                        "pattern": "^[^\\p{Cc}]{0,500}$"
                      }
                    }
                  },
                  "required": [
                    "from",
                    "to",
                    "subject"
                  ]
                }
              },
              "examples": {
                "example": {
                  "summary": "One invoice",
                  "value": [
                    {
                      "from": {
                        "email": "no-reply@example.se",
                        "name": "Example AB"
                      },
                      "to": [
                        "anna@example.com"
                      ],
                      "subject": "Your invoice for September",
                      "text": "Hi Anna, your invoice is attached.",
                      "attachments": [
                        {
                          "name": "invoice.pdf",
                          "content": "JVBERi0xLjcK",
                          "contentType": "application/pdf"
                        }
                      ],
                      "tag": "invoice",
                      "metadata": {
                        "invoiceId": "2026-0912"
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[^\\p{Cc}]{1,255}$"
            },
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "description": "Any text of 1 to 255 printable characters that identifies this batch; the same key with a different item is refused for that item."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Every message answered on its own; the batch as a whole never fails halfway.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "items": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "messageId": {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                                "description": "The id the message log, the events and the webhooks refer to."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "accepted"
                                ]
                              },
                              "submittedAt": {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                                "description": "When the message was accepted."
                              },
                              "test": {
                                "type": "boolean",
                                "description": "True when the server is a test server: the message goes through everything but delivery, and nobody receives it."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "replayed": {
                                "type": "boolean",
                                "description": "True when an earlier request under the same key already sent this item."
                              }
                            },
                            "required": [
                              "messageId",
                              "status",
                              "submittedAt",
                              "test",
                              "index",
                              "replayed"
                            ],
                            "additionalProperties": false,
                            "description": "The message was accepted for delivery."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "invalid_request"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "issues": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "path": {
                                      "type": "string",
                                      "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                                    },
                                    "message": {
                                      "type": "string"
                                    }
                                  },
                                  "required": [
                                    "path",
                                    "message"
                                  ],
                                  "additionalProperties": false
                                },
                                "description": "One entry per invalid field."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "issues",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "The message does not match what a send takes."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "from_domain_not_verified"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "The From domain is not a verified sending domain of this server."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "stream_not_found"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "The streamId names no stream of this server."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "stream_archived"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "The stream is archived and takes no new messages."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "stream_paused"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "Sendora has paused the stream after complaints; it takes no messages until support has resumed it."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "stream_not_sendable"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "An inbound stream receives mail; it takes no messages and has no suppression list. Name a transactional or broadcast stream."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "unsubscribe_placeholder_missing"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "A message on a broadcast stream must carry {{ unsubscribe_url }} in every part it has."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "list_unsubscribe_reserved"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "On a broadcast stream Sendora writes the List-Unsubscribe pair itself, so a message may not carry one."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "recipient_suppressed"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "streamId": {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                                "description": "The stream whose suppression list refused the send."
                              },
                              "suppressed": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "address": {
                                      "type": "string"
                                    },
                                    "reason": {
                                      "type": "string",
                                      "enum": [
                                        "hard_bounce",
                                        "spam_complaint",
                                        "manual",
                                        "unsubscribe"
                                      ]
                                    }
                                  },
                                  "required": [
                                    "address",
                                    "reason"
                                  ],
                                  "additionalProperties": false
                                },
                                "description": "Each refused address, lower-cased, with the reason it is on the list."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "streamId",
                              "suppressed",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "One or more recipients are on the suppression list of the stream."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "test_address_on_live_server"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "addresses": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                },
                                "description": "The recipients at simulator.sendora.se, each once."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "addresses",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "Addresses at simulator.sendora.se act out an outcome on a test server; a live server never sends to them."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "idempotency_key_mismatch"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "The Idempotency-Key was already used for a different request."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "rate_limited"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "scope": {
                                "type": "string",
                                "enum": [
                                  "account",
                                  "server",
                                  "test"
                                ],
                                "description": "Whose limit it is: `account` for the account's, `server` for the server's own, `test` for the cap the account's test servers share."
                              },
                              "limit": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "Emails per minute allowed for that scope."
                              },
                              "retryAfter": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "Seconds until the next send is accepted; also sent as the Retry-After header."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "scope",
                              "limit",
                              "retryAfter",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "More was sent within a minute than the limit allows."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "monthly_cap_reached"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "scope": {
                                "type": "string",
                                "enum": [
                                  "account",
                                  "server",
                                  "test"
                                ],
                                "description": "Whose limit it is: `account` for the account's, `server` for the server's own, `test` for the cap the account's test servers share."
                              },
                              "cap": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "Emails the scope may send in a calendar month, in UTC."
                              },
                              "used": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "Emails sent this month, the refused send not counted."
                              },
                              "resetsAt": {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                                "description": "When the month counter resets."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "scope",
                              "cap",
                              "used",
                              "resetsAt",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "The monthly cap of the account, the server or the test servers is used up."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "sending_disabled"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "Sending is disabled for everyone for the moment; retry after the seconds in Retry-After."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "account_paused"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "The account is paused by Sendora."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "account_not_active"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "The account is closed, or not yet approved for a live server's sends or an inbound stream."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "error": {
                                "type": "string",
                                "enum": [
                                  "payment_required"
                                ]
                              },
                              "message": {
                                "type": "string",
                                "description": "What went wrong, for a person to read."
                              },
                              "index": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991,
                                "description": "The position of the message in the request."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "error"
                                ]
                              }
                            },
                            "required": [
                              "error",
                              "message",
                              "index",
                              "status"
                            ],
                            "additionalProperties": false,
                            "description": "The account has no active subscription."
                          }
                        ]
                      },
                      "description": "One result per message, in request order."
                    }
                  },
                  "required": [
                    "results"
                  ],
                  "additionalProperties": false,
                  "description": "Every message answered on its own; the batch as a whole never fails halfway."
                },
                "examples": {
                  "example": {
                    "summary": "One accepted message",
                    "value": {
                      "results": [
                        {
                          "index": 0,
                          "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                          "status": "accepted",
                          "submittedAt": "2026-09-15T12:00:00.000Z",
                          "test": false,
                          "replayed": false
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes, or the Idempotency-Key header is missing.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "invalid_request"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "issues": {
                          "description": "One entry per invalid field; absent when a header is wrong.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string",
                                "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                              },
                              "message": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "path",
                              "message"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The body, the query or a header does not match what the route takes.",
                      "examples": [
                        {
                          "error": "invalid_request",
                          "message": "The request is invalid: to.0: Invalid email address",
                          "issues": [
                            {
                              "path": "to.0",
                              "message": "Invalid email address"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "idempotency_key_required"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "Batch sends need an Idempotency-Key header."
                    }
                  ],
                  "description": "The body, the query or a header does not match what the route takes, or the Idempotency-Key header is missing."
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "402": {
            "description": "The account has no active subscription.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "payment_required"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The account has no active subscription."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind, or the account is paused, closed or not yet approved for a live server's sends.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "wrong_token_kind"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "account_paused"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The account is paused by Sendora."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "account_not_active"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The account is closed, or not yet approved for a live server's sends or an inbound stream."
                    }
                  ],
                  "description": "The key is of the other kind, or the account is paused, closed or not yet approved for a live server's sends."
                }
              }
            }
          },
          "413": {
            "description": "The body exceeds 10 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "request_too_large"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body exceeds 10 MB."
                }
              }
            }
          },
          "503": {
            "description": "Sending is disabled for everyone for the moment; retry after the seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before trying again."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "sending_disabled"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "Sending is disabled for everyone for the moment; retry after the seconds in Retry-After."
                }
              }
            }
          }
        }
      }
    },
    "/v1/broadcasts": {
      "post": {
        "summary": "Send a broadcast",
        "tags": [
          "Broadcasts"
        ],
        "description": "Stores the content once and one message per entry of `messages`, up to 50,000, on a broadcast stream, in one transaction. Each message is a message in the log with its own events and webhooks, sent with the recipient’s own unsubscribe link where `{{ unsubscribe_url }}` stands. Each message may carry `substitutions`, up to 20 strings that replace `{{ key }}` in the subject, the text and the HTML, escaped in the HTML; a key the content names must be given by every message. Addresses on the stream’s suppression list are dropped and counted; a list with nothing left, a missing placeholder, a missing substitution, a transactional or archived stream and a count over the monthly cap are refused whole. The Idempotency-Key is required: a retry under the same key answers the same broadcast.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "streamId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "The broadcast stream of this server the messages go on."
                  },
                  "from": {
                    "description": "The sender. Its domain must be a verified sending domain of the server.",
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "email",
                        "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                      },
                      {
                        "type": "object",
                        "properties": {
                          "email": {
                            "type": "string",
                            "format": "email",
                            "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                          },
                          "name": {
                            "default": null,
                            "description": "A display name of up to 200 characters.",
                            "anyOf": [
                              {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "email"
                        ]
                      }
                    ]
                  },
                  "subject": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 998,
                    "description": "The subject line."
                  },
                  "text": {
                    "description": "The plain-text part, with {{ unsubscribe_url }} where the link goes. At least one of text and html is required.",
                    "type": "string",
                    "minLength": 1
                  },
                  "html": {
                    "description": "The HTML part, with {{ unsubscribe_url }} where the link goes.",
                    "type": "string",
                    "minLength": 1
                  },
                  "headers": {
                    "default": {},
                    "description": "Custom headers on every message, at most 20. The List-Unsubscribe pair is Sendora’s too. Sendora writes these itself, so a message may not set them: From, Sender, To, Cc, Bcc, Subject, Date, Message-ID, MIME-Version, Return-Path, Received, Delivered-To, DKIM-Signature, DomainKey-Signature, Authentication-Results, Received-SPF, and any name that starts with Content-, Resent-, ARC- or X-Kumo.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string",
                      "pattern": "^[^\\p{Cc}]{1,998}$"
                    }
                  },
                  "attachments": {
                    "description": "At most 20, sent with every message. A message with its attachments encoded may be at most 10 MB.",
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "name": {
                          "type": "string",
                          "pattern": "^[^\\p{Cc}/\\\\]{1,255}$"
                        },
                        "content": {
                          "type": "string",
                          "format": "byte",
                          "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$"
                        },
                        "contentType": {
                          "type": "string",
                          "pattern": "^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$"
                        },
                        "contentId": {
                          "default": null,
                          "anyOf": [
                            {
                              "type": "string",
                              "pattern": "^[^\\s<>\\p{Cc}]{1,255}$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "name",
                        "content"
                      ]
                    }
                  },
                  "tag": {
                    "default": null,
                    "description": "A label of up to 100 characters, returned with the message and its events.",
                    "anyOf": [
                      {
                        "type": "string",
                        "pattern": "^[^\\p{Cc}]{1,100}$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "metadata": {
                    "default": {},
                    "description": "Up to 20 key-value pairs of your own, on the broadcast and on every message.",
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string",
                      "pattern": "^[^\\p{Cc}]{0,500}$"
                    }
                  },
                  "messages": {
                    "minItems": 1,
                    "maxItems": 50000,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "to": {
                          "minItems": 1,
                          "type": "array",
                          "items": {
                            "description": "An address as a plain string, or an object with the address and a display name.",
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "email",
                                "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "email": {
                                    "type": "string",
                                    "format": "email",
                                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                                  },
                                  "name": {
                                    "default": null,
                                    "description": "A display name of up to 200 characters.",
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 200
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  }
                                },
                                "required": [
                                  "email"
                                ]
                              }
                            ]
                          },
                          "description": "Recipients of this message; at most 50 across to, cc and bcc."
                        },
                        "cc": {
                          "description": "Copied recipients, shown in the message.",
                          "type": "array",
                          "items": {
                            "description": "An address as a plain string, or an object with the address and a display name.",
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "email",
                                "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "email": {
                                    "type": "string",
                                    "format": "email",
                                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                                  },
                                  "name": {
                                    "default": null,
                                    "description": "A display name of up to 200 characters.",
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 200
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  }
                                },
                                "required": [
                                  "email"
                                ]
                              }
                            ]
                          }
                        },
                        "bcc": {
                          "description": "Blind-copied recipients.",
                          "type": "array",
                          "items": {
                            "description": "An address as a plain string, or an object with the address and a display name.",
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "email",
                                "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "email": {
                                    "type": "string",
                                    "format": "email",
                                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                                  },
                                  "name": {
                                    "default": null,
                                    "description": "A display name of up to 200 characters.",
                                    "anyOf": [
                                      {
                                        "type": "string",
                                        "minLength": 1,
                                        "maxLength": 200
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  }
                                },
                                "required": [
                                  "email"
                                ]
                              }
                            ]
                          }
                        },
                        "metadata": {
                          "default": {},
                          "description": "Up to 20 key-value pairs for this message, merged over the broadcast's.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string",
                            "pattern": "^[^\\p{Cc}]{0,500}$"
                          }
                        },
                        "headers": {
                          "default": {},
                          "description": "Custom headers for this message, merged over the broadcast's.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string",
                            "pattern": "^[^\\p{Cc}]{1,998}$"
                          }
                        },
                        "substitutions": {
                          "default": {},
                          "description": "Up to 20 strings that replace {{ key }} in the subject, the text and the HTML of this message; a key the content names must be given.",
                          "type": "object",
                          "propertyNames": {
                            "type": "string"
                          },
                          "additionalProperties": {
                            "type": "string",
                            "pattern": "^[^\\p{Cc}]{0,500}$"
                          }
                        }
                      },
                      "required": [
                        "to"
                      ]
                    },
                    "description": "One entry per message, at most 50000; a larger list is several broadcasts under one tag."
                  }
                },
                "required": [
                  "streamId",
                  "from",
                  "subject",
                  "messages"
                ]
              },
              "examples": {
                "example": {
                  "summary": "A newsletter to two people",
                  "value": {
                    "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                    "from": {
                      "email": "news@acme.se",
                      "name": "Acme"
                    },
                    "subject": "News from Acme in October",
                    "text": "Hi!\n\nHere is the news for October.\n\nRather not get these? {{ unsubscribe_url }}",
                    "html": "<p>Hi!</p><p>Here is the news for October.</p><p><a href=\"{{ unsubscribe_url }}\">Unsubscribe</a></p>",
                    "tag": "newsletter-2026-10",
                    "messages": [
                      {
                        "to": [
                          "anna@example.com"
                        ],
                        "metadata": {
                          "customer": "1042"
                        }
                      },
                      {
                        "to": [
                          {
                            "email": "bo@example.com",
                            "name": "Bo Berg"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[^\\p{Cc}]{1,255}$"
            },
            "in": "header",
            "name": "idempotency-key",
            "required": true,
            "description": "Any text of 1 to 255 printable characters that identifies this broadcast; the same key with a different body is refused."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "The broadcast was stored; Sendora sends its messages from here.",
            "headers": {
              "Idempotent-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                "description": "true when this is the first answer again, to a request sent before under the same Idempotency-Key; absent otherwise."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "broadcastId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The id the messages, the progress and the cancel refer to."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "accepted"
                      ]
                    },
                    "total": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Messages stored; each is a message in the log."
                    },
                    "suppressed": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Addresses dropped for standing on the stream’s suppression list."
                    },
                    "submittedAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "test": {
                      "type": "boolean",
                      "description": "True when the server is a test server: the messages go through everything but delivery, and nobody receives them."
                    }
                  },
                  "required": [
                    "broadcastId",
                    "status",
                    "total",
                    "suppressed",
                    "submittedAt",
                    "test"
                  ],
                  "additionalProperties": false,
                  "description": "The broadcast was stored; Sendora sends its messages from here."
                },
                "examples": {
                  "example": {
                    "summary": "Accepted",
                    "value": {
                      "broadcastId": "2f1c8a4e-3b6d-4f0a-9c21-7d5e6a8b9c01",
                      "status": "accepted",
                      "total": 2,
                      "suppressed": 0,
                      "submittedAt": "2026-10-01T08:00:00.000Z",
                      "test": false
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes, or the Idempotency-Key header is missing.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "invalid_request"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "issues": {
                          "description": "One entry per invalid field; absent when a header is wrong.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string",
                                "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                              },
                              "message": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "path",
                              "message"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The body, the query or a header does not match what the route takes.",
                      "examples": [
                        {
                          "error": "invalid_request",
                          "message": "The request is invalid: to.0: Invalid email address",
                          "issues": [
                            {
                              "path": "to.0",
                              "message": "Invalid email address"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "idempotency_key_required"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "Batch sends need an Idempotency-Key header."
                    }
                  ],
                  "description": "The body, the query or a header does not match what the route takes, or the Idempotency-Key header is missing."
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "402": {
            "description": "The account has no active subscription.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "payment_required"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The account has no active subscription."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind, or the account is paused, closed or not yet approved for a live server's sends.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "wrong_token_kind"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "account_paused"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The account is paused by Sendora."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "account_not_active"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The account is closed, or not yet approved for a live server's sends or an inbound stream."
                    }
                  ],
                  "description": "The key is of the other kind, or the account is paused, closed or not yet approved for a live server's sends."
                }
              }
            }
          },
          "413": {
            "description": "The body exceeds 10 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "request_too_large"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body exceeds 10 MB."
                }
              }
            }
          },
          "422": {
            "description": "The broadcast cannot be sent as it stands; the code says why.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "from_domain_not_verified"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The From domain is not a verified sending domain of this server."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_not_found"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The streamId names no stream of this server."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_archived"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The stream is archived and takes no new messages."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_paused"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "Sendora has paused the stream after complaints; it takes no messages until support has resumed it."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_not_broadcast"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "A broadcast goes on a broadcast stream; the streamId names a transactional one."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "unsubscribe_placeholder_missing"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "A message on a broadcast stream must carry {{ unsubscribe_url }} in every part it has."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "list_unsubscribe_reserved"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "On a broadcast stream Sendora writes the List-Unsubscribe pair itself, so a message may not carry one."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "substitution_missing"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "index": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "The position of the message in `messages`."
                        },
                        "keys": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "The keys the content names that the message lacks."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "index",
                        "keys"
                      ],
                      "additionalProperties": false,
                      "description": "The subject, text or HTML names a {{ key }} that a message does not give.",
                      "examples": [
                        {
                          "error": "substitution_missing",
                          "message": "The content names {{ firstName }}, which message 1 does not give.",
                          "index": 1,
                          "keys": [
                            "firstName"
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "recipient_suppressed"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "streamId": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                          "description": "The stream whose suppression list refused the send."
                        },
                        "suppressed": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "address": {
                                "type": "string"
                              },
                              "reason": {
                                "type": "string",
                                "enum": [
                                  "hard_bounce",
                                  "spam_complaint",
                                  "manual",
                                  "unsubscribe"
                                ]
                              }
                            },
                            "required": [
                              "address",
                              "reason"
                            ],
                            "additionalProperties": false
                          },
                          "description": "Each refused address, lower-cased, with the reason it is on the list."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "streamId",
                        "suppressed"
                      ],
                      "additionalProperties": false,
                      "description": "One or more recipients are on the suppression list of the stream.",
                      "examples": [
                        {
                          "error": "recipient_suppressed",
                          "message": "One or more recipients are on the suppression list of this stream; suppressed says which and why.",
                          "streamId": "3d1a2b4c-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "suppressed": [
                            {
                              "address": "anna@example.com",
                              "reason": "hard_bounce"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "test_address_on_live_server"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "addresses": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "The recipients at simulator.sendora.se, each once."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "addresses"
                      ],
                      "additionalProperties": false,
                      "description": "Addresses at simulator.sendora.se act out an outcome on a test server; a live server never sends to them.",
                      "examples": [
                        {
                          "error": "test_address_on_live_server",
                          "message": "Addresses at simulator.sendora.se act out an outcome on a test server and are never sent to from a live one. Send them from a test server.",
                          "addresses": [
                            "hardbounce@simulator.sendora.se"
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "idempotency_key_mismatch"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The Idempotency-Key was already used for a different request."
                    }
                  ],
                  "description": "The broadcast cannot be sent as it stands; the code says why."
                }
              }
            }
          },
          "429": {
            "description": "The monthly cap of the account, the server or the test servers is used up.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "monthly_cap_reached"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "scope": {
                      "type": "string",
                      "enum": [
                        "account",
                        "server",
                        "test"
                      ],
                      "description": "Whose limit it is: `account` for the account's, `server` for the server's own, `test` for the cap the account's test servers share."
                    },
                    "cap": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Emails the scope may send in a calendar month, in UTC."
                    },
                    "used": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Emails sent this month, the refused send not counted."
                    },
                    "resetsAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                      "description": "When the month counter resets."
                    }
                  },
                  "required": [
                    "error",
                    "message",
                    "scope",
                    "cap",
                    "used",
                    "resetsAt"
                  ],
                  "additionalProperties": false,
                  "description": "The monthly cap of the account, the server or the test servers is used up."
                },
                "example": {
                  "error": "monthly_cap_reached",
                  "message": "This account has used 50000 of 50000 emails this month. The cap resets at 2026-11-01T00:00:00.000Z.",
                  "scope": "account",
                  "cap": 50000,
                  "used": 50000,
                  "resetsAt": "2026-11-01T00:00:00.000Z"
                }
              }
            }
          },
          "503": {
            "description": "Sending is disabled for everyone for the moment; retry after the seconds in Retry-After.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before trying again."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "sending_disabled"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "Sending is disabled for everyone for the moment; retry after the seconds in Retry-After."
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List the broadcasts",
        "tags": [
          "Broadcasts"
        ],
        "description": "The broadcasts of this server, newest first, a page at a time.",
        "parameters": [
          {
            "schema": {
              "default": 50,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Page size, 1 to 100."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            "in": "query",
            "name": "after",
            "required": false,
            "description": "The `next` value of the previous page."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the broadcasts, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "broadcasts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "broadcastId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "streamId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                            "description": "The broadcast stream the messages go on."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "accepted",
                              "processing",
                              "completed",
                              "cancelled"
                            ],
                            "description": "accepted until the first message leaves, processing while messages are leaving, completed when every message has left or failed, cancelled once cancelled."
                          },
                          "from": {
                            "type": "string"
                          },
                          "subject": {
                            "type": "string"
                          },
                          "tag": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "metadata": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            }
                          },
                          "total": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Messages stored, after suppressed addresses were dropped."
                          },
                          "released": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Messages handed to the mail server so far."
                          },
                          "failed": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Messages that could not be handed over, cancelled ones included."
                          },
                          "suppressed": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Addresses dropped from the list for standing on the stream’s suppression list."
                          },
                          "submittedAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "completedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Set once nothing is left to send, or on cancel."
                          }
                        },
                        "required": [
                          "broadcastId",
                          "streamId",
                          "status",
                          "from",
                          "subject",
                          "tag",
                          "metadata",
                          "total",
                          "released",
                          "failed",
                          "suppressed",
                          "submittedAt",
                          "completedAt"
                        ],
                        "additionalProperties": false,
                        "description": "A broadcast and how far it has come."
                      }
                    },
                    "next": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Pass as `after` for the next page; null on the last."
                    }
                  },
                  "required": [
                    "broadcasts",
                    "next"
                  ],
                  "additionalProperties": false,
                  "description": "A page of the broadcasts, newest first."
                },
                "examples": {
                  "example": {
                    "summary": "One broadcast under way",
                    "value": {
                      "broadcasts": [
                        {
                          "broadcastId": "2f1c8a4e-3b6d-4f0a-9c21-7d5e6a8b9c01",
                          "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                          "status": "processing",
                          "from": "news@acme.se",
                          "subject": "News from Acme in October",
                          "tag": "newsletter-2026-10",
                          "metadata": {},
                          "total": 2,
                          "released": 1,
                          "failed": 0,
                          "suppressed": 0,
                          "submittedAt": "2026-10-01T08:00:00.000Z",
                          "completedAt": null
                        }
                      ],
                      "next": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/broadcasts/{id}": {
      "get": {
        "summary": "Get a broadcast",
        "tags": [
          "Broadcasts"
        ],
        "description": "The broadcast and how far it has come: its status and the counts of messages released and failed.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The broadcast id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A broadcast and how far it has come.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "broadcastId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The broadcast stream the messages go on."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "accepted",
                        "processing",
                        "completed",
                        "cancelled"
                      ],
                      "description": "accepted until the first message leaves, processing while messages are leaving, completed when every message has left or failed, cancelled once cancelled."
                    },
                    "from": {
                      "type": "string"
                    },
                    "subject": {
                      "type": "string"
                    },
                    "tag": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Messages stored, after suppressed addresses were dropped."
                    },
                    "released": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Messages handed to the mail server so far."
                    },
                    "failed": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Messages that could not be handed over, cancelled ones included."
                    },
                    "suppressed": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Addresses dropped from the list for standing on the stream’s suppression list."
                    },
                    "submittedAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "completedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set once nothing is left to send, or on cancel."
                    }
                  },
                  "required": [
                    "broadcastId",
                    "streamId",
                    "status",
                    "from",
                    "subject",
                    "tag",
                    "metadata",
                    "total",
                    "released",
                    "failed",
                    "suppressed",
                    "submittedAt",
                    "completedAt"
                  ],
                  "additionalProperties": false,
                  "description": "A broadcast and how far it has come."
                },
                "examples": {
                  "example": {
                    "summary": "Under way",
                    "value": {
                      "broadcastId": "2f1c8a4e-3b6d-4f0a-9c21-7d5e6a8b9c01",
                      "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "status": "processing",
                      "from": "news@acme.se",
                      "subject": "News from Acme in October",
                      "tag": "newsletter-2026-10",
                      "metadata": {},
                      "total": 2,
                      "released": 1,
                      "failed": 0,
                      "suppressed": 0,
                      "submittedAt": "2026-10-01T08:00:00.000Z",
                      "completedAt": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such broadcast of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such broadcast of this server."
                }
              }
            }
          }
        }
      }
    },
    "/v1/broadcasts/{id}/cancel": {
      "post": {
        "summary": "Cancel a broadcast",
        "tags": [
          "Broadcasts"
        ],
        "description": "Holds every message of the broadcast that has not been handed to the mail server yet; those count as failed. A message already on its way is delivered. A completed or cancelled broadcast answers 409.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The broadcast id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A broadcast and how far it has come.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "broadcastId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The broadcast stream the messages go on."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "accepted",
                        "processing",
                        "completed",
                        "cancelled"
                      ],
                      "description": "accepted until the first message leaves, processing while messages are leaving, completed when every message has left or failed, cancelled once cancelled."
                    },
                    "from": {
                      "type": "string"
                    },
                    "subject": {
                      "type": "string"
                    },
                    "tag": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Messages stored, after suppressed addresses were dropped."
                    },
                    "released": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Messages handed to the mail server so far."
                    },
                    "failed": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Messages that could not be handed over, cancelled ones included."
                    },
                    "suppressed": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Addresses dropped from the list for standing on the stream’s suppression list."
                    },
                    "submittedAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "completedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set once nothing is left to send, or on cancel."
                    }
                  },
                  "required": [
                    "broadcastId",
                    "streamId",
                    "status",
                    "from",
                    "subject",
                    "tag",
                    "metadata",
                    "total",
                    "released",
                    "failed",
                    "suppressed",
                    "submittedAt",
                    "completedAt"
                  ],
                  "additionalProperties": false,
                  "description": "A broadcast and how far it has come."
                },
                "examples": {
                  "example": {
                    "summary": "Cancelled",
                    "value": {
                      "broadcastId": "2f1c8a4e-3b6d-4f0a-9c21-7d5e6a8b9c01",
                      "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "status": "cancelled",
                      "from": "news@acme.se",
                      "subject": "News from Acme in October",
                      "tag": "newsletter-2026-10",
                      "metadata": {},
                      "total": 2,
                      "released": 1,
                      "failed": 1,
                      "suppressed": 0,
                      "submittedAt": "2026-10-01T08:00:00.000Z",
                      "completedAt": "2026-10-01T08:05:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such broadcast of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such broadcast of this server."
                }
              }
            }
          },
          "409": {
            "description": "The broadcast is completed or cancelled already; nothing is left to cancel.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "broadcast_not_open"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The broadcast is completed or cancelled already; nothing is left to cancel."
                }
              }
            }
          }
        }
      }
    },
    "/v1/messages/{id}": {
      "get": {
        "summary": "Read a message",
        "tags": [
          "Messages"
        ],
        "description": "The message as the log holds it, its attachments described but not returned, and every event on its timeline. Bodies are never returned.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The message id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "The message with its attachments described and its timeline.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "messageId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The stream the message went on."
                    },
                    "broadcastId": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The broadcast the message belongs to; null for a message sent on its own."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "accepted",
                        "injected",
                        "failed"
                      ],
                      "description": "`accepted` until handed to the mail server, `injected` after; `failed` if that never worked."
                    },
                    "from": {
                      "type": "string"
                    },
                    "subject": {
                      "type": "string"
                    },
                    "tag": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "metadata": {
                      "type": "object",
                      "propertyNames": {
                        "type": "string"
                      },
                      "additionalProperties": {
                        "type": "string"
                      }
                    },
                    "submittedAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "test": {
                      "type": "boolean",
                      "description": "True when the message went through a test server: its events were simulated and nobody received it."
                    },
                    "recipients": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "address": {
                            "type": "string"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "to",
                              "cc",
                              "bcc"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "delivered",
                              "deferred",
                              "bounced",
                              "expired"
                            ],
                            "description": "queued until the receiver answers; deferred while it keeps saying try later."
                          }
                        },
                        "required": [
                          "address",
                          "kind",
                          "status"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "attachments": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "contentType": {
                            "type": "string"
                          },
                          "contentId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "size": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Bytes before encoding."
                          }
                        },
                        "required": [
                          "name",
                          "contentType",
                          "contentId",
                          "size"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "recipient": {
                            "description": "The recipient the event is about; null when it concerns the message as a whole.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "Reception",
                              "Delivery",
                              "Bounce",
                              "TransientFailure",
                              "Expiration",
                              "AdminBounce",
                              "OOB",
                              "Feedback",
                              "AdminRebind",
                              "DeferredInjectionRebind",
                              "Rejection",
                              "Delayed"
                            ],
                            "description": "Reception when the mail server took it, Delivery, TransientFailure, Bounce, OOB for a bounce report received by mail, Feedback for a spam complaint."
                          },
                          "at": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "code": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The SMTP status code the receiver answered."
                          },
                          "details": {
                            "description": "The receiver’s response text.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "classification": {
                            "description": "How a bounce was classified, such as InvalidRecipient.",
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "recipient",
                          "type",
                          "at",
                          "code",
                          "details",
                          "classification"
                        ],
                        "additionalProperties": false,
                        "description": "One step of the message’s timeline."
                      },
                      "description": "Oldest first."
                    }
                  },
                  "required": [
                    "messageId",
                    "streamId",
                    "broadcastId",
                    "status",
                    "from",
                    "subject",
                    "tag",
                    "metadata",
                    "submittedAt",
                    "test",
                    "recipients",
                    "attachments",
                    "events"
                  ],
                  "additionalProperties": false,
                  "description": "The message with its attachments described and its timeline."
                },
                "examples": {
                  "example": {
                    "summary": "A delivered message",
                    "value": {
                      "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                      "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "broadcastId": null,
                      "status": "injected",
                      "from": "no-reply@example.se",
                      "subject": "Your invoice for September",
                      "tag": "invoice",
                      "metadata": {
                        "invoiceId": "2026-0912"
                      },
                      "submittedAt": "2026-09-15T12:00:00.000Z",
                      "test": false,
                      "recipients": [
                        {
                          "address": "anna@example.com",
                          "kind": "to",
                          "status": "delivered"
                        }
                      ],
                      "attachments": [
                        {
                          "name": "invoice.pdf",
                          "contentType": "application/pdf",
                          "contentId": null,
                          "size": 48213
                        }
                      ],
                      "events": [
                        {
                          "recipient": "anna@example.com",
                          "type": "Reception",
                          "at": "2026-09-15T12:00:00.000Z",
                          "code": 250,
                          "details": null,
                          "classification": null
                        },
                        {
                          "recipient": "anna@example.com",
                          "type": "Delivery",
                          "at": "2026-09-15T12:00:02.000Z",
                          "code": 250,
                          "details": "2.0.0 OK",
                          "classification": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such message of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such message of this server."
                }
              }
            }
          }
        }
      }
    },
    "/v1/messages/search": {
      "post": {
        "summary": "Search the message log",
        "tags": [
          "Messages"
        ],
        "description": "The messages of the server, newest first, one page at a time. A POST so that an address travels in the body and never in a URL. Messages older than the retention window are gone.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "recipient": {
                    "description": "Messages to this address, in to, cc or bcc.",
                    "type": "string",
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "streamId": {
                    "description": "Messages on this stream of the server.",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "broadcastId": {
                    "description": "Messages of this broadcast.",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "tag": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "status": {
                    "description": "Messages with at least one recipient in this state.",
                    "type": "string",
                    "enum": [
                      "queued",
                      "delivered",
                      "deferred",
                      "bounced",
                      "expired"
                    ]
                  },
                  "from": {
                    "description": "Submitted at or after this time.",
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                  },
                  "to": {
                    "description": "Submitted before this time.",
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                  },
                  "limit": {
                    "default": 50,
                    "description": "Page size, 1 to 100.",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100
                  },
                  "after": {
                    "description": "The `next` value of the previous page.",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "additionalProperties": false,
                "description": "Every filter is optional; the page is newest first."
              },
              "examples": {
                "example": {
                  "summary": "Bounced messages to one address",
                  "value": {
                    "recipient": "anna@example.com",
                    "status": "bounced",
                    "limit": 20
                  }
                }
              }
            }
          },
          "description": "Every filter is optional; the page is newest first."
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the messages that match, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "messages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "messageId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "streamId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                            "description": "The stream the message went on."
                          },
                          "broadcastId": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The broadcast the message belongs to; null for a message sent on its own."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "accepted",
                              "injected",
                              "failed"
                            ],
                            "description": "`accepted` until handed to the mail server, `injected` after; `failed` if that never worked."
                          },
                          "from": {
                            "type": "string"
                          },
                          "subject": {
                            "type": "string"
                          },
                          "tag": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "metadata": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {
                              "type": "string"
                            }
                          },
                          "submittedAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "test": {
                            "type": "boolean",
                            "description": "True when the message went through a test server: its events were simulated and nobody received it."
                          },
                          "recipients": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "address": {
                                  "type": "string"
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "to",
                                    "cc",
                                    "bcc"
                                  ]
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "queued",
                                    "delivered",
                                    "deferred",
                                    "bounced",
                                    "expired"
                                  ],
                                  "description": "queued until the receiver answers; deferred while it keeps saying try later."
                                }
                              },
                              "required": [
                                "address",
                                "kind",
                                "status"
                              ],
                              "additionalProperties": false
                            }
                          }
                        },
                        "required": [
                          "messageId",
                          "streamId",
                          "broadcastId",
                          "status",
                          "from",
                          "subject",
                          "tag",
                          "metadata",
                          "submittedAt",
                          "test",
                          "recipients"
                        ],
                        "additionalProperties": false,
                        "description": "A message as the log lists it."
                      }
                    },
                    "next": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Pass as `after` for the next page; null on the last."
                    }
                  },
                  "required": [
                    "messages",
                    "next"
                  ],
                  "additionalProperties": false,
                  "description": "A page of the messages that match, newest first."
                },
                "examples": {
                  "example": {
                    "summary": "One message",
                    "value": {
                      "messages": [
                        {
                          "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                          "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                          "broadcastId": null,
                          "status": "injected",
                          "from": "no-reply@example.se",
                          "subject": "Your invoice for September",
                          "tag": "invoice",
                          "metadata": {
                            "invoiceId": "2026-0912"
                          },
                          "submittedAt": "2026-09-15T12:00:00.000Z",
                          "test": false,
                          "recipients": [
                            {
                              "address": "anna@example.com",
                              "kind": "to",
                              "status": "delivered"
                            }
                          ]
                        }
                      ],
                      "next": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound/search": {
      "post": {
        "summary": "Search received messages",
        "tags": [
          "Inbound"
        ],
        "description": "The messages the server has received, newest first, one page at a time. A POST so that an address travels in the body and never in a URL. The sender is matched by keyed hash, so the search itself stores no address. Messages older than 13 months are gone.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "streamId": {
                    "description": "Messages received on this inbound stream of the server.",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "from": {
                    "description": "Messages from this address, in the envelope or the From header.",
                    "type": "string",
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "recipient": {
                    "description": "Messages sent to this address of yours, the envelope recipient.",
                    "type": "string",
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "mailboxHash": {
                    "description": "Messages whose address carried this text after the plus sign.",
                    "type": "string",
                    "maxLength": 255
                  },
                  "receivedFrom": {
                    "description": "Accepted at or after this time.",
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                  },
                  "receivedTo": {
                    "description": "Accepted before this time.",
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                  },
                  "limit": {
                    "default": 50,
                    "description": "Page size, 1 to 100.",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100
                  },
                  "after": {
                    "description": "The `next` value of the previous page.",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "additionalProperties": false,
                "description": "Every filter is optional; the page is newest first."
              },
              "examples": {
                "example": {
                  "summary": "Messages from one sender this week",
                  "value": {
                    "from": "anna@example.com",
                    "receivedFrom": "2026-09-15T00:00:00+02:00",
                    "limit": 20
                  }
                }
              }
            }
          },
          "description": "Every filter is optional; the page is newest first."
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the received messages that match, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "messages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "inboundMessageId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "streamId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                            "description": "The inbound stream that received it."
                          },
                          "receivedAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                            "description": "When the message was accepted from the sending server."
                          },
                          "envelopeRecipient": {
                            "type": "string",
                            "description": "The address of yours the message was sent to."
                          },
                          "mailboxHash": {
                            "description": "The text after the plus sign in that address, when the sender used one.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "sizeBytes": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "attachmentCount": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "hasText": {
                            "type": "boolean"
                          },
                          "hasHtml": {
                            "type": "boolean"
                          },
                          "parseIssue": {
                            "description": "What the parser met; null when the message parsed clean. A hard issue empties the parsed parts, and the raw message stays: `no_headers`, `header_block_too_large`, `too_many_headers`, `too_many_parts`, `nesting_too_deep`, `missing_boundary`, `decoded_too_large`, `parse_timeout`, `parser_error`. A soft issue keeps them and says what was changed or dropped: `truncated_multipart`, `too_many_attachments`, `unknown_transfer_encoding`, `undecodable_container`, `filename_sanitised`, `control_chars_stripped`, `multiple_from`, `duplicate_header`, `malformed_header_dropped`, `address_list_truncated`, `header_value_truncated`. A message with several names the hard one, or the first soft one in this order.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "authentication": {
                            "type": "object",
                            "properties": {
                              "spf": {
                                "type": "string",
                                "enum": [
                                  "pass",
                                  "fail",
                                  "softfail",
                                  "neutral",
                                  "none",
                                  "temperror",
                                  "permerror",
                                  "unchecked"
                                ],
                                "description": "SPF for the address in MAIL FROM."
                              },
                              "spfHelo": {
                                "type": "string",
                                "enum": [
                                  "pass",
                                  "fail",
                                  "softfail",
                                  "neutral",
                                  "none",
                                  "temperror",
                                  "permerror",
                                  "unchecked"
                                ],
                                "description": "SPF for the name the sending server gave in HELO."
                              },
                              "dkim": {
                                "type": "string",
                                "enum": [
                                  "pass",
                                  "fail",
                                  "none",
                                  "temperror",
                                  "permerror",
                                  "unchecked"
                                ]
                              },
                              "dmarc": {
                                "type": "string",
                                "enum": [
                                  "pass",
                                  "fail",
                                  "none",
                                  "temperror",
                                  "permerror",
                                  "unchecked"
                                ]
                              },
                              "dmarcPolicy": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "enum": [
                                      "none",
                                      "quarantine",
                                      "reject"
                                    ]
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "What the sender’s domain asks for; told only when DMARC failed."
                              },
                              "arc": {
                                "type": "string",
                                "enum": [
                                  "none",
                                  "pass",
                                  "fail",
                                  "unchecked"
                                ]
                              },
                              "checkedAt": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "format": "date-time",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ],
                                "description": "When the checks ran; null until they have."
                              }
                            },
                            "required": [
                              "spf",
                              "spfHelo",
                              "dkim",
                              "dmarc",
                              "dmarcPolicy",
                              "arc",
                              "checkedAt"
                            ],
                            "additionalProperties": false,
                            "description": "What Sendora found when it checked the message; unchecked until the checks have run."
                          },
                          "contentAvailable": {
                            "type": "boolean",
                            "description": "False once the stream’s content window has passed; only the reference remains."
                          },
                          "contentExpiresAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                            "description": "When the content goes."
                          },
                          "from": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "address": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": [
                                      "string",
                                      "null"
                                    ]
                                  }
                                },
                                "required": [
                                  "address",
                                  "name"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The From header; null without it or once the content is gone."
                          },
                          "subject": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "date": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The sender’s Date header as ISO 8601, when it was a real moment."
                          }
                        },
                        "required": [
                          "inboundMessageId",
                          "streamId",
                          "receivedAt",
                          "envelopeRecipient",
                          "mailboxHash",
                          "sizeBytes",
                          "attachmentCount",
                          "hasText",
                          "hasHtml",
                          "parseIssue",
                          "authentication",
                          "contentAvailable",
                          "contentExpiresAt",
                          "from",
                          "subject",
                          "date"
                        ],
                        "additionalProperties": false,
                        "description": "A received message as the list shows it."
                      }
                    },
                    "next": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Pass as `after` for the next page; null on the last."
                    }
                  },
                  "required": [
                    "messages",
                    "next"
                  ],
                  "additionalProperties": false,
                  "description": "A page of the received messages that match, newest first."
                },
                "examples": {
                  "example": {
                    "summary": "One received message",
                    "value": {
                      "messages": [
                        {
                          "inboundMessageId": "4d1f8b2e-9c3a-4e7b-8f21-6a5d0c9e7b31",
                          "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                          "receivedAt": "2026-09-19T08:00:02.000Z",
                          "envelopeRecipient": "7c9e6679742540de944be07fc1f90ae7@inbound.sendora.se",
                          "mailboxHash": null,
                          "sizeBytes": 48213,
                          "attachmentCount": 1,
                          "hasText": true,
                          "hasHtml": false,
                          "parseIssue": null,
                          "authentication": {
                            "spf": "pass",
                            "spfHelo": "pass",
                            "dkim": "pass",
                            "dmarc": "pass",
                            "dmarcPolicy": null,
                            "arc": "none",
                            "checkedAt": "2026-09-19T08:00:03.000Z"
                          },
                          "contentAvailable": true,
                          "contentExpiresAt": "2026-10-19T08:00:02.000Z",
                          "from": {
                            "address": "anna@example.com",
                            "name": "Anna Andersson"
                          },
                          "subject": "A question about my order",
                          "date": "2026-09-19T08:00:00.000Z"
                        }
                      ],
                      "next": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "422": {
            "description": "The streamId names no stream of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "stream_not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The streamId names no stream of this server."
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound/{id}": {
      "get": {
        "summary": "Read a received message",
        "tags": [
          "Inbound"
        ],
        "description": "The message with its envelope, parties, headers, text, HTML and attachment descriptors; the attachment bytes and the raw message are downloads of their own. Once the stream’s content window has passed, the content fields are null and contentAvailable is false.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The inbound message id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "The received message with everything but the attachment bytes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "inboundMessageId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The inbound stream that received it."
                    },
                    "receivedAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                      "description": "When the message was accepted from the sending server."
                    },
                    "envelopeRecipient": {
                      "type": "string",
                      "description": "The address of yours the message was sent to."
                    },
                    "mailboxHash": {
                      "description": "The text after the plus sign in that address, when the sender used one.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "sizeBytes": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "attachmentCount": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "hasText": {
                      "type": "boolean"
                    },
                    "hasHtml": {
                      "type": "boolean"
                    },
                    "parseIssue": {
                      "description": "What the parser met; null when the message parsed clean. A hard issue empties the parsed parts, and the raw message stays: `no_headers`, `header_block_too_large`, `too_many_headers`, `too_many_parts`, `nesting_too_deep`, `missing_boundary`, `decoded_too_large`, `parse_timeout`, `parser_error`. A soft issue keeps them and says what was changed or dropped: `truncated_multipart`, `too_many_attachments`, `unknown_transfer_encoding`, `undecodable_container`, `filename_sanitised`, `control_chars_stripped`, `multiple_from`, `duplicate_header`, `malformed_header_dropped`, `address_list_truncated`, `header_value_truncated`. A message with several names the hard one, or the first soft one in this order.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "authentication": {
                      "type": "object",
                      "properties": {
                        "spf": {
                          "type": "string",
                          "enum": [
                            "pass",
                            "fail",
                            "softfail",
                            "neutral",
                            "none",
                            "temperror",
                            "permerror",
                            "unchecked"
                          ],
                          "description": "SPF for the address in MAIL FROM."
                        },
                        "spfHelo": {
                          "type": "string",
                          "enum": [
                            "pass",
                            "fail",
                            "softfail",
                            "neutral",
                            "none",
                            "temperror",
                            "permerror",
                            "unchecked"
                          ],
                          "description": "SPF for the name the sending server gave in HELO."
                        },
                        "dkim": {
                          "type": "string",
                          "enum": [
                            "pass",
                            "fail",
                            "none",
                            "temperror",
                            "permerror",
                            "unchecked"
                          ]
                        },
                        "dmarc": {
                          "type": "string",
                          "enum": [
                            "pass",
                            "fail",
                            "none",
                            "temperror",
                            "permerror",
                            "unchecked"
                          ]
                        },
                        "dmarcPolicy": {
                          "anyOf": [
                            {
                              "type": "string",
                              "enum": [
                                "none",
                                "quarantine",
                                "reject"
                              ]
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "What the sender’s domain asks for; told only when DMARC failed."
                        },
                        "arc": {
                          "type": "string",
                          "enum": [
                            "none",
                            "pass",
                            "fail",
                            "unchecked"
                          ]
                        },
                        "checkedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ],
                          "description": "When the checks ran; null until they have."
                        }
                      },
                      "required": [
                        "spf",
                        "spfHelo",
                        "dkim",
                        "dmarc",
                        "dmarcPolicy",
                        "arc",
                        "checkedAt"
                      ],
                      "additionalProperties": false,
                      "description": "What Sendora found when it checked the message; unchecked until the checks have run."
                    },
                    "contentAvailable": {
                      "type": "boolean",
                      "description": "False once the stream’s content window has passed; only the reference remains."
                    },
                    "contentExpiresAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                      "description": "When the content goes."
                    },
                    "from": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "address": {
                              "type": "string"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "address",
                            "name"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The From header; null without it or once the content is gone."
                    },
                    "subject": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "date": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The sender’s Date header as ISO 8601, when it was a real moment."
                    },
                    "envelope": {
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "sender": {
                              "description": "The MAIL FROM address; null for a bounce.",
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "sender"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Null once the content is gone."
                    },
                    "replyTo": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "address": {
                            "type": "string"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "address",
                          "name"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "to": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "address": {
                            "type": "string"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "address",
                          "name"
                        ],
                        "additionalProperties": false
                      },
                      "description": "Up to 100 entries; toCount is the whole number."
                    },
                    "toCount": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "cc": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "address": {
                            "type": "string"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "address",
                          "name"
                        ],
                        "additionalProperties": false
                      },
                      "description": "Up to 100 entries; ccCount is the whole number."
                    },
                    "ccCount": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "messageIdHeader": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "inReplyTo": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "references": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "headers": {
                      "anyOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "value": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "name",
                              "value"
                            ],
                            "additionalProperties": false
                          }
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Every header in order; null once the content is gone."
                    },
                    "text": {
                      "description": "The plain-text body; null without one or once the content is gone.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "html": {
                      "description": "The HTML body as received; null without one or once the content is gone.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "attachments": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "attachmentId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "position": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Its place among the message’s attachments, from 0."
                          },
                          "name": {
                            "description": "The filename, sanitised; null once the content is gone.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "contentType": {
                            "description": "The type the sender declared; every download is served as application/octet-stream.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "contentId": {
                            "description": "The Content-ID an HTML body refers to with cid:.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "size": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Bytes."
                          },
                          "inline": {
                            "type": "boolean",
                            "description": "True for a part shown in the body rather than offered as a file."
                          }
                        },
                        "required": [
                          "attachmentId",
                          "position",
                          "name",
                          "contentType",
                          "contentId",
                          "size",
                          "inline"
                        ],
                        "additionalProperties": false,
                        "description": "An attachment of a received message; its bytes are a download of their own."
                      }
                    }
                  },
                  "required": [
                    "inboundMessageId",
                    "streamId",
                    "receivedAt",
                    "envelopeRecipient",
                    "mailboxHash",
                    "sizeBytes",
                    "attachmentCount",
                    "hasText",
                    "hasHtml",
                    "parseIssue",
                    "authentication",
                    "contentAvailable",
                    "contentExpiresAt",
                    "from",
                    "subject",
                    "date",
                    "envelope",
                    "replyTo",
                    "to",
                    "toCount",
                    "cc",
                    "ccCount",
                    "messageIdHeader",
                    "inReplyTo",
                    "references",
                    "headers",
                    "text",
                    "html",
                    "attachments"
                  ],
                  "additionalProperties": false,
                  "description": "The received message with everything but the attachment bytes."
                },
                "examples": {
                  "example": {
                    "summary": "A received message",
                    "value": {
                      "inboundMessageId": "4d1f8b2e-9c3a-4e7b-8f21-6a5d0c9e7b31",
                      "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "receivedAt": "2026-09-19T08:00:02.000Z",
                      "envelopeRecipient": "7c9e6679742540de944be07fc1f90ae7@inbound.sendora.se",
                      "mailboxHash": null,
                      "sizeBytes": 48213,
                      "attachmentCount": 1,
                      "hasText": true,
                      "hasHtml": false,
                      "parseIssue": null,
                      "authentication": {
                        "spf": "pass",
                        "spfHelo": "pass",
                        "dkim": "pass",
                        "dmarc": "pass",
                        "dmarcPolicy": null,
                        "arc": "none",
                        "checkedAt": "2026-09-19T08:00:03.000Z"
                      },
                      "contentAvailable": true,
                      "contentExpiresAt": "2026-10-19T08:00:02.000Z",
                      "from": {
                        "address": "anna@example.com",
                        "name": "Anna Andersson"
                      },
                      "subject": "A question about my order",
                      "date": "2026-09-19T08:00:00.000Z",
                      "envelope": {
                        "sender": "anna@example.com"
                      },
                      "replyTo": [],
                      "to": [
                        {
                          "address": "7c9e6679742540de944be07fc1f90ae7@inbound.sendora.se",
                          "name": null
                        }
                      ],
                      "toCount": 1,
                      "cc": [],
                      "ccCount": 0,
                      "messageIdHeader": "<question-1@example.com>",
                      "inReplyTo": null,
                      "references": [],
                      "headers": [
                        {
                          "name": "From",
                          "value": "Anna Andersson <anna@example.com>"
                        },
                        {
                          "name": "Subject",
                          "value": "A question about my order"
                        }
                      ],
                      "text": "Hi!\n",
                      "html": null,
                      "attachments": [
                        {
                          "attachmentId": "9b7e2c41-3f6d-4a8e-b2c5-1d0f7e6a9c58",
                          "position": 0,
                          "name": "invoice.pdf",
                          "contentType": "application/pdf",
                          "contentId": null,
                          "size": 46102,
                          "inline": false
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such inbound message of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such inbound message of this server."
                }
              }
            }
          },
          "409": {
            "description": "The stored content of this received message cannot be opened. Sendora has been told.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "content_unreadable"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The stored content of this received message cannot be opened. Sendora has been told."
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound/{id}/raw": {
      "get": {
        "summary": "Download the raw message",
        "tags": [
          "Inbound"
        ],
        "description": "The message byte for byte as it was received, as message/rfc822 under Content-Disposition: attachment. 410 once the content window has passed.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The inbound message id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "The raw message.",
            "content": {
              "message/rfc822": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such inbound message of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such inbound message of this server."
                }
              }
            }
          },
          "409": {
            "description": "The stored content of this received message cannot be opened. Sendora has been told.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "content_unreadable"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The stored content of this received message cannot be opened. Sendora has been told."
                }
              }
            }
          },
          "410": {
            "description": "The content of this received message is gone; the stream’s content window has passed. The message itself stays 13 months.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "content_expired"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The content of this received message is gone; the stream’s content window has passed. The message itself stays 13 months."
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound/{id}/attachments/{attachmentId}": {
      "get": {
        "summary": "Download an attachment",
        "tags": [
          "Inbound"
        ],
        "description": "The attachment’s bytes as application/octet-stream whatever the sender declared, under Content-Disposition: attachment with its sanitised name. 410 once the content window has passed.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The inbound message id."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "attachmentId",
            "required": true,
            "description": "The attachment id, from the message."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "The attachment.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such inbound message of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such inbound message of this server."
                }
              }
            }
          },
          "409": {
            "description": "The stored content of this received message cannot be opened. Sendora has been told.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "content_unreadable"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The stored content of this received message cannot be opened. Sendora has been told."
                }
              }
            }
          },
          "410": {
            "description": "The content of this received message is gone; the stream’s content window has passed. The message itself stays 13 months.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "content_expired"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The content of this received message is gone; the stream’s content window has passed. The message itself stays 13 months."
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound/domains": {
      "post": {
        "summary": "Claim a domain for an inbound stream",
        "tags": [
          "Inbound"
        ],
        "description": "Claims the domain for one of the server’s inbound streams and answers the two DNS records to add: an MX that brings the domain’s mail to Sendora and a TXT record that proves the claim. Mail to any address on the domain is accepted once both records are seen, which Sendora checks on its own and on request. A stream holds one domain; the first account to verify a name holds it.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "streamId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "An inbound stream of the server."
                  },
                  "domain": {
                    "type": "string",
                    "description": "The domain mail is sent from, such as example.se; lower-cased and IDNA-encoded."
                  }
                },
                "required": [
                  "streamId",
                  "domain"
                ]
              },
              "examples": {
                "example": {
                  "summary": "A domain",
                  "value": {
                    "streamId": "b7d2e4f6-1a3c-4d5e-9f80-2c4e6a8b0d1f",
                    "domain": "post.example.se"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "201": {
            "description": "A domain on an inbound stream and the two records it needs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "inboundDomainId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The inbound stream the domain delivers to."
                    },
                    "domain": {
                      "type": "string",
                      "description": "The domain, lower-cased and IDNA-encoded."
                    },
                    "verified": {
                      "type": "boolean",
                      "description": "True while both records are seen; only then is mail to the domain accepted."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "lastCheckedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the records were last looked up."
                    },
                    "unverifiedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When a verified domain lost its records. Mail to it is deferred for 72 hours from then and refused after, until the records are back."
                    },
                    "mx": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "MX"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The MX record that brings the domain’s mail to Sendora, at any priority."
                    },
                    "txt": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "TXT"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The TXT record that proves the claim; it carries a value only you were shown."
                    }
                  },
                  "required": [
                    "inboundDomainId",
                    "streamId",
                    "domain",
                    "verified",
                    "createdAt",
                    "lastCheckedAt",
                    "unverifiedAt",
                    "mx",
                    "txt"
                  ],
                  "additionalProperties": false,
                  "description": "A domain on an inbound stream and the two records it needs."
                },
                "examples": {
                  "example": {
                    "summary": "A new domain",
                    "value": {
                      "inboundDomainId": "6c2a9e1d-3f4b-4a8c-9d0e-1b2c3d4e5f60",
                      "streamId": "b7d2e4f6-1a3c-4d5e-9f80-2c4e6a8b0d1f",
                      "domain": "post.example.se",
                      "verified": false,
                      "createdAt": "2026-09-19T09:00:00.000Z",
                      "lastCheckedAt": null,
                      "unverifiedAt": null,
                      "mx": {
                        "type": "MX",
                        "host": "post.example.se",
                        "value": "10 inbound.sendora.se.",
                        "verified": false,
                        "verifiedAt": null
                      },
                      "txt": {
                        "type": "TXT",
                        "host": "_sendora-inbound.post.example.se",
                        "value": "sendora-inbound=7f3a9c2e5b1d4f6a8c0e2b4d6f8a1c3e",
                        "verified": false,
                        "verifiedAt": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body does not match what the route takes, or the domain is reserved.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "invalid_request"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "issues": {
                          "description": "One entry per invalid field; absent when a header is wrong.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string",
                                "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                              },
                              "message": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "path",
                              "message"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The body, the query or a header does not match what the route takes.",
                      "examples": [
                        {
                          "error": "invalid_request",
                          "message": "The request is invalid: to.0: Invalid email address",
                          "issues": [
                            {
                              "path": "to.0",
                              "message": "Invalid email address"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "domain_reserved"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The name is Sendora’s own, or a return-path host; no account can receive on it."
                    }
                  ],
                  "description": "The body does not match what the route takes, or the domain is reserved."
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "409": {
            "description": "The stream already has a domain, or another account holds the name verified.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "inbound_domain_exists"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "inboundDomainId": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The domain the stream already has, when that is the reason; null when another account holds the name verified."
                    }
                  },
                  "required": [
                    "error",
                    "message",
                    "inboundDomainId"
                  ],
                  "additionalProperties": false,
                  "description": "The stream already has a domain, or another account holds the name verified."
                },
                "example": {
                  "error": "inbound_domain_exists",
                  "message": "The stream already has a domain; remove it first.",
                  "inboundDomainId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                }
              }
            }
          },
          "422": {
            "description": "The streamId names no stream of this server, or an archived one.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_not_found"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The streamId names no stream of this server."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_archived"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The stream is archived and takes no new messages."
                    }
                  ],
                  "description": "The streamId names no stream of this server, or an archived one."
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List the inbound domains",
        "tags": [
          "Inbound"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Every inbound domain of the server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domains": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "inboundDomainId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "streamId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                            "description": "The inbound stream the domain delivers to."
                          },
                          "domain": {
                            "type": "string",
                            "description": "The domain, lower-cased and IDNA-encoded."
                          },
                          "verified": {
                            "type": "boolean",
                            "description": "True while both records are seen; only then is mail to the domain accepted."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "lastCheckedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When the records were last looked up."
                          },
                          "unverifiedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When a verified domain lost its records. Mail to it is deferred for 72 hours from then and refused after, until the records are back."
                          },
                          "mx": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "enum": [
                                  "MX"
                                ]
                              },
                              "host": {
                                "type": "string",
                                "description": "The name to create the record under."
                              },
                              "value": {
                                "type": "string",
                                "description": "The value the record must hold."
                              },
                              "verified": {
                                "type": "boolean"
                              },
                              "verifiedAt": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "format": "date-time",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "type",
                              "host",
                              "value",
                              "verified",
                              "verifiedAt"
                            ],
                            "additionalProperties": false,
                            "description": "The MX record that brings the domain’s mail to Sendora, at any priority."
                          },
                          "txt": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "enum": [
                                  "TXT"
                                ]
                              },
                              "host": {
                                "type": "string",
                                "description": "The name to create the record under."
                              },
                              "value": {
                                "type": "string",
                                "description": "The value the record must hold."
                              },
                              "verified": {
                                "type": "boolean"
                              },
                              "verifiedAt": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "format": "date-time",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "type",
                              "host",
                              "value",
                              "verified",
                              "verifiedAt"
                            ],
                            "additionalProperties": false,
                            "description": "The TXT record that proves the claim; it carries a value only you were shown."
                          }
                        },
                        "required": [
                          "inboundDomainId",
                          "streamId",
                          "domain",
                          "verified",
                          "createdAt",
                          "lastCheckedAt",
                          "unverifiedAt",
                          "mx",
                          "txt"
                        ],
                        "additionalProperties": false,
                        "description": "A domain on an inbound stream and the two records it needs."
                      }
                    }
                  },
                  "required": [
                    "domains"
                  ],
                  "additionalProperties": false,
                  "description": "Every inbound domain of the server."
                },
                "examples": {
                  "example": {
                    "summary": "One domain",
                    "value": {
                      "domains": [
                        {
                          "inboundDomainId": "6c2a9e1d-3f4b-4a8c-9d0e-1b2c3d4e5f60",
                          "streamId": "b7d2e4f6-1a3c-4d5e-9f80-2c4e6a8b0d1f",
                          "domain": "post.example.se",
                          "verified": false,
                          "createdAt": "2026-09-19T09:00:00.000Z",
                          "lastCheckedAt": null,
                          "unverifiedAt": null,
                          "mx": {
                            "type": "MX",
                            "host": "post.example.se",
                            "value": "10 inbound.sendora.se.",
                            "verified": false,
                            "verifiedAt": null
                          },
                          "txt": {
                            "type": "TXT",
                            "host": "_sendora-inbound.post.example.se",
                            "value": "sendora-inbound=7f3a9c2e5b1d4f6a8c0e2b4d6f8a1c3e",
                            "verified": false,
                            "verifiedAt": null
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound/domains/{id}": {
      "get": {
        "summary": "Read an inbound domain",
        "tags": [
          "Inbound"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The inbound domain id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A domain on an inbound stream and the two records it needs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "inboundDomainId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The inbound stream the domain delivers to."
                    },
                    "domain": {
                      "type": "string",
                      "description": "The domain, lower-cased and IDNA-encoded."
                    },
                    "verified": {
                      "type": "boolean",
                      "description": "True while both records are seen; only then is mail to the domain accepted."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "lastCheckedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the records were last looked up."
                    },
                    "unverifiedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When a verified domain lost its records. Mail to it is deferred for 72 hours from then and refused after, until the records are back."
                    },
                    "mx": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "MX"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The MX record that brings the domain’s mail to Sendora, at any priority."
                    },
                    "txt": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "TXT"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The TXT record that proves the claim; it carries a value only you were shown."
                    }
                  },
                  "required": [
                    "inboundDomainId",
                    "streamId",
                    "domain",
                    "verified",
                    "createdAt",
                    "lastCheckedAt",
                    "unverifiedAt",
                    "mx",
                    "txt"
                  ],
                  "additionalProperties": false,
                  "description": "A domain on an inbound stream and the two records it needs."
                },
                "examples": {
                  "example": {
                    "summary": "A domain",
                    "value": {
                      "inboundDomainId": "6c2a9e1d-3f4b-4a8c-9d0e-1b2c3d4e5f60",
                      "streamId": "b7d2e4f6-1a3c-4d5e-9f80-2c4e6a8b0d1f",
                      "domain": "post.example.se",
                      "verified": false,
                      "createdAt": "2026-09-19T09:00:00.000Z",
                      "lastCheckedAt": null,
                      "unverifiedAt": null,
                      "mx": {
                        "type": "MX",
                        "host": "post.example.se",
                        "value": "10 inbound.sendora.se.",
                        "verified": false,
                        "verifiedAt": null
                      },
                      "txt": {
                        "type": "TXT",
                        "host": "_sendora-inbound.post.example.se",
                        "value": "sendora-inbound=7f3a9c2e5b1d4f6a8c0e2b4d6f8a1c3e",
                        "verified": false,
                        "verifiedAt": null
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such inbound domain of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such inbound domain of this server."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Remove an inbound domain",
        "tags": [
          "Inbound"
        ],
        "description": "Mail to the domain is refused from then on, and the name is free for another claim. What was received stays on the stream.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The inbound domain id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "204": {
            "description": "Removed. The body is empty."
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such inbound domain of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such inbound domain of this server."
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound/domains/{id}/verify": {
      "post": {
        "summary": "Check the records now",
        "tags": [
          "Inbound"
        ],
        "description": "Looks both records up at once and records the result; the answer carries the domain as it stands and what each lookup found. A TXT record that is right while another account holds the name verified reads as mismatch.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The inbound domain id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "The domain as it stands, with what each lookup found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "inboundDomainId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The inbound stream the domain delivers to."
                    },
                    "domain": {
                      "type": "string",
                      "description": "The domain, lower-cased and IDNA-encoded."
                    },
                    "verified": {
                      "type": "boolean",
                      "description": "True while both records are seen; only then is mail to the domain accepted."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "lastCheckedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the records were last looked up."
                    },
                    "unverifiedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When a verified domain lost its records. Mail to it is deferred for 72 hours from then and refused after, until the records are back."
                    },
                    "mx": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "MX"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The MX record that brings the domain’s mail to Sendora, at any priority."
                    },
                    "txt": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "TXT"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The TXT record that proves the claim; it carries a value only you were shown."
                    },
                    "check": {
                      "type": "object",
                      "properties": {
                        "mx": {
                          "type": "string",
                          "enum": [
                            "ok",
                            "missing",
                            "mismatch",
                            "dns_error"
                          ],
                          "description": "dns_error is a resolver failure, such as a DNSSEC problem or a timeout, not an absent record."
                        },
                        "txt": {
                          "type": "string",
                          "enum": [
                            "ok",
                            "missing",
                            "mismatch",
                            "dns_error"
                          ],
                          "description": "dns_error is a resolver failure, such as a DNSSEC problem or a timeout, not an absent record."
                        }
                      },
                      "required": [
                        "mx",
                        "txt"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "inboundDomainId",
                    "streamId",
                    "domain",
                    "verified",
                    "createdAt",
                    "lastCheckedAt",
                    "unverifiedAt",
                    "mx",
                    "txt",
                    "check"
                  ],
                  "additionalProperties": false,
                  "description": "The domain as it stands, with what each lookup found."
                },
                "examples": {
                  "example": {
                    "summary": "Records still missing",
                    "value": {
                      "inboundDomainId": "6c2a9e1d-3f4b-4a8c-9d0e-1b2c3d4e5f60",
                      "streamId": "b7d2e4f6-1a3c-4d5e-9f80-2c4e6a8b0d1f",
                      "domain": "post.example.se",
                      "verified": false,
                      "createdAt": "2026-09-19T09:00:00.000Z",
                      "lastCheckedAt": null,
                      "unverifiedAt": null,
                      "mx": {
                        "type": "MX",
                        "host": "post.example.se",
                        "value": "10 inbound.sendora.se.",
                        "verified": false,
                        "verifiedAt": null
                      },
                      "txt": {
                        "type": "TXT",
                        "host": "_sendora-inbound.post.example.se",
                        "value": "sendora-inbound=7f3a9c2e5b1d4f6a8c0e2b4d6f8a1c3e",
                        "verified": false,
                        "verifiedAt": null
                      },
                      "check": {
                        "mx": "missing",
                        "txt": "missing"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such inbound domain of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such inbound domain of this server."
                }
              }
            }
          }
        }
      }
    },
    "/v1/streams": {
      "post": {
        "summary": "Create a stream",
        "tags": [
          "Streams"
        ],
        "description": "Adds a stream to this server. A transactional or a broadcast stream is available to every account; an inbound stream receives mail at its own address, and a server has one at a time, and a test server none. Each sending stream has a suppression list of its own.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "transactional",
                      "broadcast",
                      "inbound"
                    ],
                    "description": "transactional or broadcast for sending, open to every account; a server has one live inbound stream."
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "1 to 100 characters."
                  }
                },
                "required": [
                  "kind",
                  "name"
                ]
              },
              "examples": {
                "example": {
                  "summary": "A second transactional stream",
                  "value": {
                    "kind": "transactional",
                    "name": "Notices"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "201": {
            "description": "A stream of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "What a send names as streamId."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "transactional",
                        "broadcast",
                        "inbound"
                      ],
                      "description": "transactional for mail the recipient expects; broadcast for mail to many; inbound for mail the server receives."
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "description": "The name given at creation, unique within the server."
                    },
                    "isDefault": {
                      "type": "boolean",
                      "description": "The stream a send without a streamId goes on; one per server, transactional."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "archivedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set once archived; the stream then takes no new messages."
                    },
                    "pausedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set while Sendora has paused the stream after complaints; it takes no messages until support has resumed it."
                    },
                    "inboundAddress": {
                      "description": "The address of an inbound stream, its id on inbound.sendora.se; mail sent there is received on the stream. Null on every other kind.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "contentRetentionDays": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 30
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "How many days an inbound stream keeps received content, 1 to 30; null means the default of 30. Null on every other kind."
                    }
                  },
                  "required": [
                    "streamId",
                    "kind",
                    "name",
                    "isDefault",
                    "createdAt",
                    "archivedAt",
                    "pausedAt",
                    "inboundAddress",
                    "contentRetentionDays"
                  ],
                  "additionalProperties": false,
                  "description": "A stream of this server."
                },
                "examples": {
                  "example": {
                    "summary": "A new stream",
                    "value": {
                      "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "kind": "transactional",
                      "name": "Notices",
                      "isDefault": false,
                      "createdAt": "2026-09-16T12:00:00.000Z",
                      "archivedAt": null,
                      "pausedAt": null,
                      "inboundAddress": null,
                      "contentRetentionDays": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind, or the account is closed or not yet approved, which an inbound stream needs.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "wrong_token_kind"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "account_not_active"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The account is closed, or not yet approved for a live server's sends or an inbound stream."
                    }
                  ],
                  "description": "The key is of the other kind, or the account is closed or not yet approved, which an inbound stream needs."
                }
              }
            }
          },
          "409": {
            "description": "The server already has a stream with this name, or an inbound stream.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_exists"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "streamId": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                          "description": "The stream that already carries the name."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "streamId"
                      ],
                      "additionalProperties": false,
                      "description": "The server already has a stream with this name, archived or not.",
                      "examples": [
                        {
                          "error": "stream_exists",
                          "message": "This server already has a stream with that name.",
                          "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "inbound_stream_exists"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "streamId": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                          "description": "The server's live inbound stream."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "streamId"
                      ],
                      "additionalProperties": false,
                      "description": "A server has one inbound stream at a time; archive it to make another.",
                      "examples": [
                        {
                          "error": "inbound_stream_exists",
                          "message": "This server already has an inbound stream. Archive it to make another; mail to the old address is then refused.",
                          "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                        }
                      ]
                    }
                  ],
                  "description": "The server already has a stream with this name, or an inbound stream."
                }
              }
            }
          },
          "422": {
            "description": "A test server has no inbound stream; receive on a live server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "stream_kind_not_allowed"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "A test server has no inbound stream; receive on a live server."
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List the streams",
        "tags": [
          "Streams"
        ],
        "description": "Every stream of the server, archived ones included, oldest first.",
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Every stream of the server, archived ones included, oldest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "streams": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "streamId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                            "description": "What a send names as streamId."
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "transactional",
                              "broadcast",
                              "inbound"
                            ],
                            "description": "transactional for mail the recipient expects; broadcast for mail to many; inbound for mail the server receives."
                          },
                          "name": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100,
                            "description": "The name given at creation, unique within the server."
                          },
                          "isDefault": {
                            "type": "boolean",
                            "description": "The stream a send without a streamId goes on; one per server, transactional."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "archivedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Set once archived; the stream then takes no new messages."
                          },
                          "pausedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Set while Sendora has paused the stream after complaints; it takes no messages until support has resumed it."
                          },
                          "inboundAddress": {
                            "description": "The address of an inbound stream, its id on inbound.sendora.se; mail sent there is received on the stream. Null on every other kind.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "contentRetentionDays": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": 1,
                                "maximum": 30
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "How many days an inbound stream keeps received content, 1 to 30; null means the default of 30. Null on every other kind."
                          }
                        },
                        "required": [
                          "streamId",
                          "kind",
                          "name",
                          "isDefault",
                          "createdAt",
                          "archivedAt",
                          "pausedAt",
                          "inboundAddress",
                          "contentRetentionDays"
                        ],
                        "additionalProperties": false,
                        "description": "A stream of this server."
                      }
                    }
                  },
                  "required": [
                    "streams"
                  ],
                  "additionalProperties": false,
                  "description": "Every stream of the server, archived ones included, oldest first."
                },
                "examples": {
                  "example": {
                    "summary": "Three streams",
                    "value": {
                      "streams": [
                        {
                          "streamId": "3d1a2b4c-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "kind": "transactional",
                          "name": "transactional",
                          "isDefault": true,
                          "createdAt": "2026-09-15T12:00:00.000Z",
                          "archivedAt": null,
                          "pausedAt": null,
                          "inboundAddress": null,
                          "contentRetentionDays": null
                        },
                        {
                          "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                          "kind": "transactional",
                          "name": "Notices",
                          "isDefault": false,
                          "createdAt": "2026-09-16T12:00:00.000Z",
                          "archivedAt": null,
                          "pausedAt": null,
                          "inboundAddress": null,
                          "contentRetentionDays": null
                        },
                        {
                          "streamId": "9b2f7c41-3e5d-4a8b-9c1e-2d3f4a5b6c7d",
                          "kind": "inbound",
                          "name": "Support",
                          "isDefault": false,
                          "createdAt": "2026-09-20T12:00:00.000Z",
                          "archivedAt": null,
                          "pausedAt": null,
                          "inboundAddress": "9b2f7c413e5d4a8b9c1e2d3f4a5b6c7d@inbound.sendora.se",
                          "contentRetentionDays": 14
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/streams/{id}": {
      "get": {
        "summary": "Read a stream",
        "tags": [
          "Streams"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The stream id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A stream of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "What a send names as streamId."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "transactional",
                        "broadcast",
                        "inbound"
                      ],
                      "description": "transactional for mail the recipient expects; broadcast for mail to many; inbound for mail the server receives."
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "description": "The name given at creation, unique within the server."
                    },
                    "isDefault": {
                      "type": "boolean",
                      "description": "The stream a send without a streamId goes on; one per server, transactional."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "archivedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set once archived; the stream then takes no new messages."
                    },
                    "pausedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set while Sendora has paused the stream after complaints; it takes no messages until support has resumed it."
                    },
                    "inboundAddress": {
                      "description": "The address of an inbound stream, its id on inbound.sendora.se; mail sent there is received on the stream. Null on every other kind.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "contentRetentionDays": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 30
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "How many days an inbound stream keeps received content, 1 to 30; null means the default of 30. Null on every other kind."
                    }
                  },
                  "required": [
                    "streamId",
                    "kind",
                    "name",
                    "isDefault",
                    "createdAt",
                    "archivedAt",
                    "pausedAt",
                    "inboundAddress",
                    "contentRetentionDays"
                  ],
                  "additionalProperties": false,
                  "description": "A stream of this server."
                },
                "examples": {
                  "example": {
                    "summary": "A stream",
                    "value": {
                      "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "kind": "transactional",
                      "name": "Notices",
                      "isDefault": false,
                      "createdAt": "2026-09-16T12:00:00.000Z",
                      "archivedAt": null,
                      "pausedAt": null,
                      "inboundAddress": null,
                      "contentRetentionDays": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such stream of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such stream of this server."
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a stream",
        "tags": [
          "Streams"
        ],
        "description": "The id stays. A new name must be free within the server. contentRetentionDays applies to an inbound stream only and sets how long received content is kept.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "1 to 100 characters."
                  },
                  "contentRetentionDays": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 30
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Days an inbound stream keeps received content, 1 to 30; null for the default of 30."
                  }
                }
              },
              "examples": {
                "example": {
                  "summary": "A new name",
                  "value": {
                    "name": "Driftinformation"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The stream id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A stream of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "What a send names as streamId."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "transactional",
                        "broadcast",
                        "inbound"
                      ],
                      "description": "transactional for mail the recipient expects; broadcast for mail to many; inbound for mail the server receives."
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "description": "The name given at creation, unique within the server."
                    },
                    "isDefault": {
                      "type": "boolean",
                      "description": "The stream a send without a streamId goes on; one per server, transactional."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "archivedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set once archived; the stream then takes no new messages."
                    },
                    "pausedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set while Sendora has paused the stream after complaints; it takes no messages until support has resumed it."
                    },
                    "inboundAddress": {
                      "description": "The address of an inbound stream, its id on inbound.sendora.se; mail sent there is received on the stream. Null on every other kind.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "contentRetentionDays": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 30
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "How many days an inbound stream keeps received content, 1 to 30; null means the default of 30. Null on every other kind."
                    }
                  },
                  "required": [
                    "streamId",
                    "kind",
                    "name",
                    "isDefault",
                    "createdAt",
                    "archivedAt",
                    "pausedAt",
                    "inboundAddress",
                    "contentRetentionDays"
                  ],
                  "additionalProperties": false,
                  "description": "A stream of this server."
                },
                "examples": {
                  "example": {
                    "summary": "The updated stream",
                    "value": {
                      "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "kind": "transactional",
                      "name": "Driftinformation",
                      "isDefault": false,
                      "createdAt": "2026-09-16T12:00:00.000Z",
                      "archivedAt": null,
                      "pausedAt": null,
                      "inboundAddress": null,
                      "contentRetentionDays": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such stream of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such stream of this server."
                }
              }
            }
          },
          "409": {
            "description": "The server already has a stream with this name, archived or not.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "stream_exists"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The stream that already carries the name."
                    }
                  },
                  "required": [
                    "error",
                    "message",
                    "streamId"
                  ],
                  "additionalProperties": false,
                  "description": "The server already has a stream with this name, archived or not."
                },
                "example": {
                  "error": "stream_exists",
                  "message": "This server already has a stream with that name.",
                  "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                }
              }
            }
          }
        }
      }
    },
    "/v1/streams/{id}/archive": {
      "post": {
        "summary": "Archive a stream",
        "tags": [
          "Streams"
        ],
        "description": "The stream takes no new messages from now on; what it already holds is still delivered, and its log and suppression list stay readable. An archived inbound stream refuses mail to its address, and the server may create another. Archiving an archived stream changes nothing. The default stream cannot be archived.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The stream id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A stream of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "streamId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "What a send names as streamId."
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "transactional",
                        "broadcast",
                        "inbound"
                      ],
                      "description": "transactional for mail the recipient expects; broadcast for mail to many; inbound for mail the server receives."
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "description": "The name given at creation, unique within the server."
                    },
                    "isDefault": {
                      "type": "boolean",
                      "description": "The stream a send without a streamId goes on; one per server, transactional."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "archivedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set once archived; the stream then takes no new messages."
                    },
                    "pausedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Set while Sendora has paused the stream after complaints; it takes no messages until support has resumed it."
                    },
                    "inboundAddress": {
                      "description": "The address of an inbound stream, its id on inbound.sendora.se; mail sent there is received on the stream. Null on every other kind.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "contentRetentionDays": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 30
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "How many days an inbound stream keeps received content, 1 to 30; null means the default of 30. Null on every other kind."
                    }
                  },
                  "required": [
                    "streamId",
                    "kind",
                    "name",
                    "isDefault",
                    "createdAt",
                    "archivedAt",
                    "pausedAt",
                    "inboundAddress",
                    "contentRetentionDays"
                  ],
                  "additionalProperties": false,
                  "description": "A stream of this server."
                },
                "examples": {
                  "example": {
                    "summary": "The archived stream",
                    "value": {
                      "streamId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                      "kind": "transactional",
                      "name": "Notices",
                      "isDefault": false,
                      "createdAt": "2026-09-16T12:00:00.000Z",
                      "archivedAt": "2026-09-16T13:00:00.000Z",
                      "pausedAt": null,
                      "inboundAddress": null,
                      "contentRetentionDays": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such stream of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such stream of this server."
                }
              }
            }
          },
          "409": {
            "description": "The default stream of a server cannot be archived.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "default_stream"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The default stream of a server cannot be archived."
                }
              }
            }
          }
        }
      }
    },
    "/v1/suppressions": {
      "get": {
        "summary": "List the suppressed addresses",
        "tags": [
          "Suppressions"
        ],
        "description": "Addresses a stream of the server will not send to: hard bounces, spam complaints and entries added by hand, newest first, one page at a time. The default stream unless streamId names another; every stream has a list of its own. A send to any of them is refused with recipient_suppressed.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            "in": "query",
            "name": "streamId",
            "required": false,
            "description": "The stream whose list is meant; the default transactional stream when absent."
          },
          {
            "schema": {
              "default": 100,
              "type": "integer",
              "minimum": 1,
              "maximum": 1000
            },
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Page size, 1 to 1000."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            "in": "query",
            "name": "after",
            "required": false,
            "description": "The `next` value of the previous page."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the stream's suppression list, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "suppressions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "streamId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                            "description": "The stream whose list the address is on."
                          },
                          "address": {
                            "type": "string",
                            "description": "The recipient, lower-cased."
                          },
                          "reason": {
                            "type": "string",
                            "enum": [
                              "hard_bounce",
                              "spam_complaint",
                              "manual",
                              "unsubscribe"
                            ],
                            "description": "A hard bounce or a manual entry may be lifted here; a spam complaint or the recipient’s own unsubscribe only by Sendora support. manual is an address added by hand in the dashboard."
                          },
                          "messageId": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The message whose bounce or complaint put it here."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          }
                        },
                        "required": [
                          "streamId",
                          "address",
                          "reason",
                          "messageId",
                          "createdAt"
                        ],
                        "additionalProperties": false,
                        "description": "An address this stream no longer sends to."
                      }
                    },
                    "next": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Pass as `after` for the next page; null on the last."
                    }
                  },
                  "required": [
                    "suppressions",
                    "next"
                  ],
                  "additionalProperties": false,
                  "description": "A page of the stream's suppression list, newest first."
                },
                "examples": {
                  "example": {
                    "summary": "One address",
                    "value": {
                      "suppressions": [
                        {
                          "streamId": "3d1a2b4c-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "address": "anna@example.com",
                          "reason": "hard_bounce",
                          "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                          "createdAt": "2026-09-15T12:00:00.000Z"
                        }
                      ],
                      "next": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "422": {
            "description": "The streamId names no stream of this server, or an inbound stream.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_not_found"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The streamId names no stream of this server."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_not_sendable"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "An inbound stream receives mail; it takes no messages and has no suppression list. Name a transactional or broadcast stream."
                    }
                  ],
                  "description": "The streamId names no stream of this server, or an inbound stream."
                }
              }
            }
          }
        }
      }
    },
    "/v1/suppressions/delete": {
      "post": {
        "summary": "Lift a suppression",
        "tags": [
          "Suppressions"
        ],
        "description": "Removes a hard-bounced or manually added address from a stream’s list so the server may send to it again on that stream. A POST, because the address travels in the body and never in a URL. A spam complaint cannot be lifted this way.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "address": {
                    "type": "string",
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
                    "description": "The address to send to again."
                  },
                  "streamId": {
                    "description": "The stream whose list is meant; the default transactional stream when absent.",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "address"
                ]
              },
              "examples": {
                "example": {
                  "summary": "An address",
                  "value": {
                    "address": "anna@example.com"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "204": {
            "description": "Removed. The body is empty."
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind, or the entry is a spam complaint or an unsubscribe, which only Sendora support lifts.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "wrong_token_kind"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "spam_complaint_locked"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The recipient reported a message as spam; only Sendora support lifts that, at the recipient’s own request."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "unsubscribe_locked"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The recipient unsubscribed themselves; only Sendora support lifts that, at the recipient’s own request."
                    }
                  ],
                  "description": "The key is of the other kind, or the entry is a spam complaint or an unsubscribe, which only Sendora support lifts."
                }
              }
            }
          },
          "404": {
            "description": "No such suppressed address of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such suppressed address of this server."
                }
              }
            }
          },
          "422": {
            "description": "The streamId names no stream of this server, or an inbound stream.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_not_found"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The streamId names no stream of this server."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "stream_not_sendable"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "An inbound stream receives mail; it takes no messages and has no suppression list. Name a transactional or broadcast stream."
                    }
                  ],
                  "description": "The streamId names no stream of this server, or an inbound stream."
                }
              }
            }
          }
        }
      }
    },
    "/v1/tokens": {
      "post": {
        "summary": "Create a key",
        "tags": [
          "Keys"
        ],
        "description": "Creates another live key for this server and answers its value once; it is never shown again. Every key of a server has the same rights. A server holds at most two live keys: the one in use and the one being rotated in.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "1 to 100 characters."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "examples": {
                "example": {
                  "summary": "A named key",
                  "value": {
                    "name": "Invoicing system"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "201": {
            "description": "The new key, its value shown this once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tokenId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "name": {
                      "type": "string",
                      "description": "The name given at creation, for people to tell keys apart."
                    },
                    "prefix": {
                      "type": "string",
                      "description": "The first characters of the key, to match it with a value in hand."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "revokedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "token": {
                      "type": "string",
                      "description": "The key itself, shown this once."
                    }
                  },
                  "required": [
                    "tokenId",
                    "name",
                    "prefix",
                    "createdAt",
                    "revokedAt",
                    "token"
                  ],
                  "additionalProperties": false,
                  "description": "The new key, its value shown this once."
                },
                "examples": {
                  "example": {
                    "summary": "A new key",
                    "value": {
                      "tokenId": "3b0c9e2f-6d4a-4e8b-8a1c-9f2d7e6c5b40",
                      "name": "Invoicing system",
                      "prefix": "sk_a1b2c3d4e5",
                      "createdAt": "2026-09-15T12:00:00.000Z",
                      "revokedAt": null,
                      "token": "sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "409": {
            "description": "The server or the account already holds two live keys: one in use and one to rotate to. Revoke one before creating another.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "token_limit"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "max": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Live keys the owner may hold at once."
                    }
                  },
                  "required": [
                    "error",
                    "message",
                    "max"
                  ],
                  "additionalProperties": false,
                  "description": "The server or the account already holds two live keys: one in use and one to rotate to. Revoke one before creating another."
                },
                "example": {
                  "error": "token_limit",
                  "message": "The server may hold at most 2 live keys; revoke one before creating another.",
                  "max": 2
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List the keys",
        "tags": [
          "Keys"
        ],
        "description": "Every key of the server, revoked ones included.",
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Every key of the server, revoked ones included.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tokens": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "tokenId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "name": {
                            "type": "string",
                            "description": "The name given at creation, for people to tell keys apart."
                          },
                          "prefix": {
                            "type": "string",
                            "description": "The first characters of the key, to match it with a value in hand."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "revokedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "tokenId",
                          "name",
                          "prefix",
                          "createdAt",
                          "revokedAt"
                        ],
                        "additionalProperties": false,
                        "description": "A key of this server; the value itself is shown only when it is created."
                      }
                    }
                  },
                  "required": [
                    "tokens"
                  ],
                  "additionalProperties": false,
                  "description": "Every key of the server, revoked ones included."
                },
                "examples": {
                  "example": {
                    "summary": "One key",
                    "value": {
                      "tokens": [
                        {
                          "tokenId": "3b0c9e2f-6d4a-4e8b-8a1c-9f2d7e6c5b40",
                          "name": "Invoicing system",
                          "prefix": "sk_a1b2c3d4e5",
                          "createdAt": "2026-09-15T12:00:00.000Z",
                          "revokedAt": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/tokens/{id}": {
      "get": {
        "summary": "Read a key",
        "tags": [
          "Keys"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The key id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A key of this server; the value itself is shown only when it is created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tokenId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "name": {
                      "type": "string",
                      "description": "The name given at creation, for people to tell keys apart."
                    },
                    "prefix": {
                      "type": "string",
                      "description": "The first characters of the key, to match it with a value in hand."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "revokedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "tokenId",
                    "name",
                    "prefix",
                    "createdAt",
                    "revokedAt"
                  ],
                  "additionalProperties": false,
                  "description": "A key of this server; the value itself is shown only when it is created."
                },
                "examples": {
                  "example": {
                    "summary": "A key",
                    "value": {
                      "tokenId": "3b0c9e2f-6d4a-4e8b-8a1c-9f2d7e6c5b40",
                      "name": "Invoicing system",
                      "prefix": "sk_a1b2c3d4e5",
                      "createdAt": "2026-09-15T12:00:00.000Z",
                      "revokedAt": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such key of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such key of this server."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Revoke a key",
        "tags": [
          "Keys"
        ],
        "description": "The key stops working at once. The last live key of a server cannot be revoked, so a server is never locked out; revoking a key that is already revoked is fine.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The key id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "204": {
            "description": "Removed. The body is empty."
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such key of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such key of this server."
                }
              }
            }
          },
          "409": {
            "description": "This is the only live key of the server; create another before revoking it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "last_token"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "This is the only live key of the server; create another before revoking it."
                }
              }
            }
          }
        }
      }
    },
    "/v1/server": {
      "get": {
        "summary": "Read this key's server",
        "tags": [
          "Servers"
        ],
        "description": "The server the key belongs to, whether it is live or a test server, every limit a send on it is held to with how much of it this minute and this month have used, and the sending domains a from address on it may use.",
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "The server this key belongs to, its mode, its limits with their use and the domains it may send from.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "serverId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The id every server key, stream and message of the server refers to."
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "description": "The name given at creation, unique within the account."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "live delivers; test goes through everything but delivery, so nothing reaches a recipient. Fixed when the server is created."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "limits": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "scope": {
                            "type": "string",
                            "enum": [
                              "account",
                              "server",
                              "test"
                            ],
                            "description": "Whose limit it is: `account` for the account's, `server` for the server's own, `test` for the cap the account's test servers share."
                          },
                          "period": {
                            "type": "string",
                            "enum": [
                              "minute",
                              "month"
                            ],
                            "description": "The UTC minute or the calendar month in UTC the limit counts over."
                          },
                          "limit": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Emails allowed in the period, one per recipient."
                          },
                          "used": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991,
                            "description": "Emails the period has taken so far."
                          },
                          "resetsAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                            "description": "When the period ends and the count starts again."
                          }
                        },
                        "required": [
                          "scope",
                          "period",
                          "limit",
                          "used",
                          "resetsAt"
                        ],
                        "additionalProperties": false,
                        "description": "One limit a send on this server is held to, and how much of it is used."
                      },
                      "description": "Every limit a single send is held to: on a live server the account's per-minute limit and monthly cap, and the server's own where Sendora set them; on a test server the test cap its account's test servers share."
                    },
                    "sendingDomains": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "domain": {
                            "type": "string",
                            "description": "The domain, as the part of a from address after the @."
                          },
                          "failingSince": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When a check first found one of its records missing or wrong; mail keeps going out, and the first check 24 hours after this that still misses one ends the verification. Null while every record is in place."
                          }
                        },
                        "required": [
                          "domain",
                          "failingSince"
                        ],
                        "additionalProperties": false,
                        "description": "A sending domain of the account that a from address may use now."
                      },
                      "description": "The account's sending domains a from address on this server may use now: every verified one, one in its 24-hour warning with failingSince set. Sending domains are the account's; an account key or the dashboard adds one."
                    }
                  },
                  "required": [
                    "serverId",
                    "name",
                    "mode",
                    "createdAt",
                    "limits",
                    "sendingDomains"
                  ],
                  "additionalProperties": false,
                  "description": "The server this key belongs to, its mode, its limits with their use and the domains it may send from."
                },
                "examples": {
                  "example": {
                    "summary": "A live server",
                    "value": {
                      "serverId": "7c1e4d2a-0b9f-4a3e-8d6c-5e2f1a9b8c70",
                      "name": "Invoicing",
                      "mode": "live",
                      "createdAt": "2026-09-20T12:00:00.000Z",
                      "limits": [
                        {
                          "scope": "account",
                          "period": "minute",
                          "limit": 300,
                          "used": 4,
                          "resetsAt": "2026-09-24T10:01:00.000Z"
                        },
                        {
                          "scope": "account",
                          "period": "month",
                          "limit": 10000,
                          "used": 812,
                          "resetsAt": "2026-10-01T00:00:00.000Z"
                        }
                      ],
                      "sendingDomains": [
                        {
                          "domain": "example.se",
                          "failingSince": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/servers": {
      "post": {
        "summary": "Create a server",
        "tags": [
          "Servers"
        ],
        "description": "Adds a server to the account with its default transactional stream and its first key, whose value is answered this once. A server holds up to two live keys, so a second can be created before the first is revoked. Names are unique within the account, and the account holds up to its cap of servers.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "1 to 100 characters."
                  },
                  "mode": {
                    "default": "live",
                    "description": "live unless told otherwise. A test server’s keys start sk_test_, and addresses at simulator.sendora.se act out a delivery, a bounce, a deferral or a complaint on it.",
                    "type": "string",
                    "enum": [
                      "live",
                      "test"
                    ]
                  }
                },
                "required": [
                  "name"
                ]
              },
              "examples": {
                "example": {
                  "summary": "A server",
                  "value": {
                    "name": "Invoicing"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "201": {
            "description": "The new server with its first key, its value shown this once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "serverId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The id every server key, stream and message of the server refers to."
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "description": "The name given at creation, unique within the account."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "live delivers; test goes through everything but delivery, so nothing reaches a recipient. Fixed when the server is created."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "token": {
                      "type": "object",
                      "properties": {
                        "tokenId": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        "name": {
                          "type": "string",
                          "description": "The name given at creation, for people to tell keys apart."
                        },
                        "prefix": {
                          "type": "string",
                          "description": "The first characters of the key, to match it with a value in hand."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        "revokedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "token": {
                          "type": "string",
                          "description": "The key itself, shown this once."
                        }
                      },
                      "required": [
                        "tokenId",
                        "name",
                        "prefix",
                        "createdAt",
                        "revokedAt",
                        "token"
                      ],
                      "additionalProperties": false,
                      "description": "The server’s first key, named default; its value is never shown again."
                    }
                  },
                  "required": [
                    "serverId",
                    "name",
                    "mode",
                    "createdAt",
                    "token"
                  ],
                  "additionalProperties": false,
                  "description": "The new server with its first key, its value shown this once."
                },
                "examples": {
                  "example": {
                    "summary": "A new server with its first key",
                    "value": {
                      "serverId": "7c1e4d2a-0b9f-4a3e-8d6c-5e2f1a9b8c70",
                      "name": "Invoicing",
                      "mode": "live",
                      "createdAt": "2026-09-20T12:00:00.000Z",
                      "token": {
                        "tokenId": "3b0c9e2f-6d4a-4e8b-8a1c-9f2d7e6c5b40",
                        "name": "default",
                        "prefix": "sk_a1b2c3d4e5",
                        "createdAt": "2026-09-20T12:00:00.000Z",
                        "revokedAt": null,
                        "token": "sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "409": {
            "description": "The account already has a server with that name, or as many servers as it may.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "server_exists"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The account already has a server with that name."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "server_limit"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "maxServers": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991,
                          "description": "Servers the account may have at once."
                        }
                      },
                      "required": [
                        "error",
                        "message",
                        "maxServers"
                      ],
                      "additionalProperties": false,
                      "description": "The account has as many servers as it may; Sendora raises the cap on request.",
                      "examples": [
                        {
                          "error": "server_limit",
                          "message": "The account may have at most 10 servers.",
                          "maxServers": 10
                        }
                      ]
                    }
                  ],
                  "description": "The account already has a server with that name, or as many servers as it may."
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List the servers",
        "tags": [
          "Servers"
        ],
        "description": "Every server of the account, oldest first.",
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Every server of the account, oldest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "servers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "serverId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                            "description": "The id every server key, stream and message of the server refers to."
                          },
                          "name": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100,
                            "description": "The name given at creation, unique within the account."
                          },
                          "mode": {
                            "type": "string",
                            "enum": [
                              "live",
                              "test"
                            ],
                            "description": "live delivers; test goes through everything but delivery, so nothing reaches a recipient. Fixed when the server is created."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          }
                        },
                        "required": [
                          "serverId",
                          "name",
                          "mode",
                          "createdAt"
                        ],
                        "additionalProperties": false,
                        "description": "A server of the account: an isolation boundary with its own keys, streams, log, suppressions and webhooks."
                      }
                    }
                  },
                  "required": [
                    "servers"
                  ],
                  "additionalProperties": false,
                  "description": "Every server of the account, oldest first."
                },
                "examples": {
                  "example": {
                    "summary": "One server",
                    "value": {
                      "servers": [
                        {
                          "serverId": "7c1e4d2a-0b9f-4a3e-8d6c-5e2f1a9b8c70",
                          "name": "Invoicing",
                          "mode": "live",
                          "createdAt": "2026-09-20T12:00:00.000Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/servers/{id}": {
      "get": {
        "summary": "Read a server",
        "tags": [
          "Servers"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The server id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "A server of the account: an isolation boundary with its own keys, streams, log, suppressions and webhooks.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "serverId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The id every server key, stream and message of the server refers to."
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "description": "The name given at creation, unique within the account."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "live delivers; test goes through everything but delivery, so nothing reaches a recipient. Fixed when the server is created."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    }
                  },
                  "required": [
                    "serverId",
                    "name",
                    "mode",
                    "createdAt"
                  ],
                  "additionalProperties": false,
                  "description": "A server of the account: an isolation boundary with its own keys, streams, log, suppressions and webhooks."
                },
                "examples": {
                  "example": {
                    "summary": "A server",
                    "value": {
                      "serverId": "7c1e4d2a-0b9f-4a3e-8d6c-5e2f1a9b8c70",
                      "name": "Invoicing",
                      "mode": "live",
                      "createdAt": "2026-09-20T12:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such server of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such server of this account."
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Rename a server",
        "tags": [
          "Servers"
        ],
        "description": "The id, the keys, the mode and everything the server holds stay. The new name must be free within the account. A body that names a mode is refused: a server is live or test from its creation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "1 to 100 characters."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "examples": {
                "example": {
                  "summary": "A new name",
                  "value": {
                    "name": "Ekonomi"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The server id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "A server of the account: an isolation boundary with its own keys, streams, log, suppressions and webhooks.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "serverId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The id every server key, stream and message of the server refers to."
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "description": "The name given at creation, unique within the account."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "live",
                        "test"
                      ],
                      "description": "live delivers; test goes through everything but delivery, so nothing reaches a recipient. Fixed when the server is created."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    }
                  },
                  "required": [
                    "serverId",
                    "name",
                    "mode",
                    "createdAt"
                  ],
                  "additionalProperties": false,
                  "description": "A server of the account: an isolation boundary with its own keys, streams, log, suppressions and webhooks."
                },
                "examples": {
                  "example": {
                    "summary": "The renamed server",
                    "value": {
                      "serverId": "7c1e4d2a-0b9f-4a3e-8d6c-5e2f1a9b8c70",
                      "name": "Ekonomi",
                      "mode": "live",
                      "createdAt": "2026-09-20T12:00:00.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body does not match what the route takes, or it asks to change the server's mode.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "invalid_request"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        },
                        "issues": {
                          "description": "One entry per invalid field; absent when a header is wrong.",
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "path": {
                                "type": "string",
                                "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                              },
                              "message": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "path",
                              "message"
                            ],
                            "additionalProperties": false
                          }
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The body, the query or a header does not match what the route takes.",
                      "examples": [
                        {
                          "error": "invalid_request",
                          "message": "The request is invalid: to.0: Invalid email address",
                          "issues": [
                            {
                              "path": "to.0",
                              "message": "Invalid email address"
                            }
                          ]
                        }
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "mode_immutable"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "A server’s mode is fixed when it is created; create a new server for the other mode."
                    }
                  ],
                  "description": "The body does not match what the route takes, or it asks to change the server's mode."
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such server of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such server of this account."
                }
              }
            }
          },
          "409": {
            "description": "The account already has a server with that name, or the server is Sendora's own.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "server_exists"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "The account already has a server with that name."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "server_reserved"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "This server sends Sendora’s own sign-in mail and cannot be renamed or removed."
                    }
                  ],
                  "description": "The account already has a server with that name, or the server is Sendora's own."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a server",
        "tags": [
          "Servers"
        ],
        "description": "Removes the server with its keys, streams, messages, suppressions and webhooks. Refused while messages of the server are still being delivered; try again once they have left. What the server sent stays counted on the account’s usage.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The server id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "204": {
            "description": "Removed. The body is empty."
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such server of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such server of this account."
                }
              }
            }
          },
          "409": {
            "description": "The server is Sendora's own, or its mail is still being delivered.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "server_reserved"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "This server sends Sendora’s own sign-in mail and cannot be renamed or removed."
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "server_in_flight"
                          ]
                        },
                        "message": {
                          "type": "string",
                          "description": "What went wrong, for a person to read."
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ],
                      "additionalProperties": false,
                      "description": "Messages of the server are still being delivered; try again once they have left."
                    }
                  ],
                  "description": "The server is Sendora's own, or its mail is still being delivered."
                }
              }
            }
          }
        }
      }
    },
    "/v1/servers/{id}/tokens": {
      "post": {
        "summary": "Create a key for a server",
        "tags": [
          "Servers"
        ],
        "description": "Creates another live key for the server and answers its value once; it is never shown again. Every key of a server has the same rights. A server holds at most two live keys: the one in use and the one being rotated in.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "1 to 100 characters."
                  }
                },
                "required": [
                  "name"
                ]
              },
              "examples": {
                "example": {
                  "summary": "A named key",
                  "value": {
                    "name": "Invoicing system"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The server id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "201": {
            "description": "The new key, its value shown this once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tokenId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "name": {
                      "type": "string",
                      "description": "The name given at creation, for people to tell keys apart."
                    },
                    "prefix": {
                      "type": "string",
                      "description": "The first characters of the key, to match it with a value in hand."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "revokedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "token": {
                      "type": "string",
                      "description": "The key itself, shown this once."
                    }
                  },
                  "required": [
                    "tokenId",
                    "name",
                    "prefix",
                    "createdAt",
                    "revokedAt",
                    "token"
                  ],
                  "additionalProperties": false,
                  "description": "The new key, its value shown this once."
                },
                "examples": {
                  "example": {
                    "summary": "A new key",
                    "value": {
                      "tokenId": "3b0c9e2f-6d4a-4e8b-8a1c-9f2d7e6c5b40",
                      "name": "Invoicing system",
                      "prefix": "sk_a1b2c3d4e5",
                      "createdAt": "2026-09-20T12:00:00.000Z",
                      "revokedAt": null,
                      "token": "sk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such server of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such server of this account."
                }
              }
            }
          },
          "409": {
            "description": "The server or the account already holds two live keys: one in use and one to rotate to. Revoke one before creating another.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "token_limit"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "max": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Live keys the owner may hold at once."
                    }
                  },
                  "required": [
                    "error",
                    "message",
                    "max"
                  ],
                  "additionalProperties": false,
                  "description": "The server or the account already holds two live keys: one in use and one to rotate to. Revoke one before creating another."
                },
                "example": {
                  "error": "token_limit",
                  "message": "The server may hold at most 2 live keys; revoke one before creating another.",
                  "max": 2
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List the keys of a server",
        "tags": [
          "Servers"
        ],
        "description": "Every key of the server, revoked ones included.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The server id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Every key of the server, revoked ones included.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tokens": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "tokenId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "name": {
                            "type": "string",
                            "description": "The name given at creation, for people to tell keys apart."
                          },
                          "prefix": {
                            "type": "string",
                            "description": "The first characters of the key, to match it with a value in hand."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "revokedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          }
                        },
                        "required": [
                          "tokenId",
                          "name",
                          "prefix",
                          "createdAt",
                          "revokedAt"
                        ],
                        "additionalProperties": false,
                        "description": "A key of this server; the value itself is shown only when it is created."
                      }
                    }
                  },
                  "required": [
                    "tokens"
                  ],
                  "additionalProperties": false,
                  "description": "Every key of the server, revoked ones included."
                },
                "examples": {
                  "example": {
                    "summary": "One key",
                    "value": {
                      "tokens": [
                        {
                          "tokenId": "3b0c9e2f-6d4a-4e8b-8a1c-9f2d7e6c5b40",
                          "name": "default",
                          "prefix": "sk_a1b2c3d4e5",
                          "createdAt": "2026-09-20T12:00:00.000Z",
                          "revokedAt": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such server of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such server of this account."
                }
              }
            }
          }
        }
      }
    },
    "/v1/servers/{id}/tokens/{tokenId}": {
      "get": {
        "summary": "Read a key of a server",
        "tags": [
          "Servers"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The server id."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "tokenId",
            "required": true,
            "description": "The key id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "A key of this server; the value itself is shown only when it is created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tokenId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "name": {
                      "type": "string",
                      "description": "The name given at creation, for people to tell keys apart."
                    },
                    "prefix": {
                      "type": "string",
                      "description": "The first characters of the key, to match it with a value in hand."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "revokedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "tokenId",
                    "name",
                    "prefix",
                    "createdAt",
                    "revokedAt"
                  ],
                  "additionalProperties": false,
                  "description": "A key of this server; the value itself is shown only when it is created."
                },
                "examples": {
                  "example": {
                    "summary": "A key",
                    "value": {
                      "tokenId": "3b0c9e2f-6d4a-4e8b-8a1c-9f2d7e6c5b40",
                      "name": "default",
                      "prefix": "sk_a1b2c3d4e5",
                      "createdAt": "2026-09-20T12:00:00.000Z",
                      "revokedAt": null
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such server of this account, or no such key of the server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such server of this account, or no such key of the server."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Revoke a key of a server",
        "tags": [
          "Servers"
        ],
        "description": "The key stops working at once. The last live key of a server cannot be revoked, so a server is never locked out; revoking a key that is already revoked is fine.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The server id."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "tokenId",
            "required": true,
            "description": "The key id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "204": {
            "description": "Removed. The body is empty."
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such server of this account, or no such key of the server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such server of this account, or no such key of the server."
                }
              }
            }
          },
          "409": {
            "description": "This is the only live key of the server; create another before revoking it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "last_token"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "This is the only live key of the server; create another before revoking it."
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks": {
      "post": {
        "summary": "Create a webhook",
        "tags": [
          "Webhooks"
        ],
        "description": "Registers a URL to receive events. The answer carries the signing secret once; every delivery is signed with it (HMAC-SHA256 over the body) so the receiver can verify Sendora sent it. A second secret can be created later to roll the first one.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "An https URL on a public host, without credentials or a fragment."
                  },
                  "events": {
                    "description": "The events to deliver; every event when left out.",
                    "minItems": 1,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "delivered",
                        "bounced",
                        "deferred",
                        "spam_complaint",
                        "unsubscribed",
                        "cap_warning",
                        "cap_reached",
                        "inbound"
                      ]
                    }
                  },
                  "streamId": {
                    "description": "Limits the message events to one stream of the server; every stream when left out. Cap events concern the server and arrive either way.",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "inboundContent": {
                    "description": "How the inbound event carries a received message: full sends the parsed message with the event; reference sends ids and sizes only, for you to fetch. full when left out.",
                    "type": "string",
                    "enum": [
                      "full",
                      "reference"
                    ]
                  }
                },
                "required": [
                  "url"
                ]
              },
              "examples": {
                "example": {
                  "summary": "Delivery and bounce events",
                  "value": {
                    "url": "https://example.se/hooks/sendora",
                    "events": [
                      "delivered",
                      "bounced",
                      "spam_complaint"
                    ]
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "201": {
            "description": "The new webhook with its signing secret, shown this once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhookId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "url": {
                      "type": "string",
                      "description": "Where the events are posted."
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "delivered",
                          "bounced",
                          "deferred",
                          "spam_complaint",
                          "unsubscribed",
                          "cap_warning",
                          "cap_reached",
                          "inbound"
                        ]
                      }
                    },
                    "streamId": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The one stream whose message events it receives; null for every stream."
                    },
                    "enabled": {
                      "type": "boolean",
                      "description": "False while switched off in the dashboard; nothing is queued for it then."
                    },
                    "inboundContent": {
                      "type": "string",
                      "enum": [
                        "full",
                        "reference"
                      ],
                      "description": "How the inbound event carries a received message: the parsed message, or a reference."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "secrets": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "secretId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          }
                        },
                        "required": [
                          "secretId",
                          "createdAt"
                        ],
                        "additionalProperties": false,
                        "description": "A live signing secret by id and age; its value was shown once when it was created."
                      },
                      "description": "The live secrets, oldest first; every delivery is signed with each of them, the newest first in Sendora-Signature."
                    },
                    "secret": {
                      "type": "string",
                      "description": "The signing secret, shown this once."
                    }
                  },
                  "required": [
                    "webhookId",
                    "url",
                    "events",
                    "streamId",
                    "enabled",
                    "inboundContent",
                    "createdAt",
                    "secrets",
                    "secret"
                  ],
                  "additionalProperties": false,
                  "description": "The new webhook with its signing secret, shown this once."
                },
                "examples": {
                  "example": {
                    "summary": "A new webhook",
                    "value": {
                      "webhookId": "7c1e4d2a-0b9f-4a3e-8d6c-5e2f1a9b8c70",
                      "url": "https://example.se/hooks/sendora",
                      "events": [
                        "delivered",
                        "bounced",
                        "spam_complaint"
                      ],
                      "streamId": null,
                      "enabled": true,
                      "inboundContent": "full",
                      "createdAt": "2026-09-15T12:00:00.000Z",
                      "secrets": [
                        {
                          "secretId": "4a5b6c7d-8e9f-4a0b-8c1d-2e3f4a5b6c7d",
                          "createdAt": "2026-09-15T12:00:00.000Z"
                        }
                      ],
                      "secret": "whsec_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "409": {
            "description": "The server already has a webhook for that URL.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "webhook_exists"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "webhookId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The id of the webhook the server already has for that URL."
                    }
                  },
                  "required": [
                    "error",
                    "message",
                    "webhookId"
                  ],
                  "additionalProperties": false,
                  "description": "The server already has a webhook for that URL."
                },
                "example": {
                  "error": "webhook_exists",
                  "message": "This server already has a webhook for that URL.",
                  "webhookId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                }
              }
            }
          },
          "422": {
            "description": "The streamId names no stream of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "stream_not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The streamId names no stream of this server."
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List the webhooks",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Every webhook of the server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhooks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "webhookId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "url": {
                            "type": "string",
                            "description": "Where the events are posted."
                          },
                          "events": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "delivered",
                                "bounced",
                                "deferred",
                                "spam_complaint",
                                "unsubscribed",
                                "cap_warning",
                                "cap_reached",
                                "inbound"
                              ]
                            }
                          },
                          "streamId": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The one stream whose message events it receives; null for every stream."
                          },
                          "enabled": {
                            "type": "boolean",
                            "description": "False while switched off in the dashboard; nothing is queued for it then."
                          },
                          "inboundContent": {
                            "type": "string",
                            "enum": [
                              "full",
                              "reference"
                            ],
                            "description": "How the inbound event carries a received message: the parsed message, or a reference."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "secrets": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "secretId": {
                                  "type": "string",
                                  "format": "uuid",
                                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                                },
                                "createdAt": {
                                  "type": "string",
                                  "format": "date-time",
                                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                                }
                              },
                              "required": [
                                "secretId",
                                "createdAt"
                              ],
                              "additionalProperties": false,
                              "description": "A live signing secret by id and age; its value was shown once when it was created."
                            },
                            "description": "The live secrets, oldest first; every delivery is signed with each of them, the newest first in Sendora-Signature."
                          }
                        },
                        "required": [
                          "webhookId",
                          "url",
                          "events",
                          "streamId",
                          "enabled",
                          "inboundContent",
                          "createdAt",
                          "secrets"
                        ],
                        "additionalProperties": false,
                        "description": "A webhook of this server."
                      }
                    }
                  },
                  "required": [
                    "webhooks"
                  ],
                  "additionalProperties": false,
                  "description": "Every webhook of the server."
                },
                "examples": {
                  "example": {
                    "summary": "One webhook",
                    "value": {
                      "webhooks": [
                        {
                          "webhookId": "7c1e4d2a-0b9f-4a3e-8d6c-5e2f1a9b8c70",
                          "url": "https://example.se/hooks/sendora",
                          "events": [
                            "delivered",
                            "bounced",
                            "spam_complaint"
                          ],
                          "streamId": null,
                          "enabled": true,
                          "inboundContent": "full",
                          "createdAt": "2026-09-15T12:00:00.000Z",
                          "secrets": [
                            {
                              "secretId": "4a5b6c7d-8e9f-4a0b-8c1d-2e3f4a5b6c7d",
                              "createdAt": "2026-09-15T12:00:00.000Z"
                            }
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{id}": {
      "get": {
        "summary": "Read a webhook",
        "tags": [
          "Webhooks"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The webhook id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A webhook of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhookId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "url": {
                      "type": "string",
                      "description": "Where the events are posted."
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "enum": [
                          "delivered",
                          "bounced",
                          "deferred",
                          "spam_complaint",
                          "unsubscribed",
                          "cap_warning",
                          "cap_reached",
                          "inbound"
                        ]
                      }
                    },
                    "streamId": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The one stream whose message events it receives; null for every stream."
                    },
                    "enabled": {
                      "type": "boolean",
                      "description": "False while switched off in the dashboard; nothing is queued for it then."
                    },
                    "inboundContent": {
                      "type": "string",
                      "enum": [
                        "full",
                        "reference"
                      ],
                      "description": "How the inbound event carries a received message: the parsed message, or a reference."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "secrets": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "secretId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          }
                        },
                        "required": [
                          "secretId",
                          "createdAt"
                        ],
                        "additionalProperties": false,
                        "description": "A live signing secret by id and age; its value was shown once when it was created."
                      },
                      "description": "The live secrets, oldest first; every delivery is signed with each of them, the newest first in Sendora-Signature."
                    }
                  },
                  "required": [
                    "webhookId",
                    "url",
                    "events",
                    "streamId",
                    "enabled",
                    "inboundContent",
                    "createdAt",
                    "secrets"
                  ],
                  "additionalProperties": false,
                  "description": "A webhook of this server."
                },
                "examples": {
                  "example": {
                    "summary": "A webhook",
                    "value": {
                      "webhookId": "7c1e4d2a-0b9f-4a3e-8d6c-5e2f1a9b8c70",
                      "url": "https://example.se/hooks/sendora",
                      "events": [
                        "delivered",
                        "bounced",
                        "spam_complaint"
                      ],
                      "streamId": null,
                      "enabled": true,
                      "inboundContent": "full",
                      "createdAt": "2026-09-15T12:00:00.000Z",
                      "secrets": [
                        {
                          "secretId": "4a5b6c7d-8e9f-4a0b-8c1d-2e3f4a5b6c7d",
                          "createdAt": "2026-09-15T12:00:00.000Z"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such webhook of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such webhook of this server."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Remove a webhook",
        "tags": [
          "Webhooks"
        ],
        "description": "Deliveries still pending are dropped with it.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The webhook id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "204": {
            "description": "Removed. The body is empty."
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such webhook of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such webhook of this server."
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{id}/deliveries": {
      "get": {
        "summary": "List the deliveries of a webhook",
        "tags": [
          "Webhooks"
        ],
        "description": "Every event handed to the webhook, newest first, one page at a time, with the outcome of the last attempt.",
        "parameters": [
          {
            "schema": {
              "default": 100,
              "type": "integer",
              "minimum": 1,
              "maximum": 1000
            },
            "in": "query",
            "name": "limit",
            "required": false,
            "description": "Page size, 1 to 1000."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            "in": "query",
            "name": "after",
            "required": false,
            "description": "The `next` value of the previous page."
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "delivered",
                "dead"
              ]
            },
            "in": "query",
            "name": "status",
            "required": false
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The webhook id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "A page of the webhook's deliveries, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deliveries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "deliveryId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "event": {
                            "type": "string",
                            "enum": [
                              "delivered",
                              "bounced",
                              "deferred",
                              "spam_complaint",
                              "unsubscribed",
                              "cap_warning",
                              "cap_reached",
                              "inbound"
                            ]
                          },
                          "messageId": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "Null for an event about usage rather than a message."
                          },
                          "inboundMessageId": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The received message an inbound event is about; null for every other event."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "delivered",
                              "dead"
                            ],
                            "description": "pending is waiting for its next attempt; dead gave up and can be replayed."
                          },
                          "attempts": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "nextAttemptAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When the next attempt is due, while pending."
                          },
                          "lastStatusCode": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "The HTTP status the endpoint last answered."
                          },
                          "lastError": {
                            "description": "Why the last attempt failed, when it did.",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "deliveredAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          }
                        },
                        "required": [
                          "deliveryId",
                          "event",
                          "messageId",
                          "inboundMessageId",
                          "status",
                          "attempts",
                          "nextAttemptAt",
                          "lastStatusCode",
                          "lastError",
                          "deliveredAt",
                          "createdAt"
                        ],
                        "additionalProperties": false,
                        "description": "One event on its way to the webhook, retried with backoff until delivered or dead."
                      }
                    },
                    "next": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Pass as `after` for the next page; null on the last."
                    }
                  },
                  "required": [
                    "deliveries",
                    "next"
                  ],
                  "additionalProperties": false,
                  "description": "A page of the webhook's deliveries, newest first."
                },
                "examples": {
                  "example": {
                    "summary": "One delivered event",
                    "value": {
                      "deliveries": [
                        {
                          "deliveryId": "9e8d7c6b-5a4f-4e3d-9c2b-1a0f9e8d7c60",
                          "event": "delivered",
                          "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                          "inboundMessageId": null,
                          "status": "delivered",
                          "attempts": 1,
                          "nextAttemptAt": null,
                          "lastStatusCode": 200,
                          "lastError": null,
                          "deliveredAt": "2026-09-15T12:00:03.000Z",
                          "createdAt": "2026-09-15T12:00:02.000Z"
                        }
                      ],
                      "next": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such webhook of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such webhook of this server."
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{id}/deliveries/{deliveryId}/replay": {
      "post": {
        "summary": "Replay a delivery",
        "tags": [
          "Webhooks"
        ],
        "description": "Queues the event for delivery again, whatever its state, with the same payload and a fresh attempt count.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The webhook id."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "deliveryId",
            "required": true,
            "description": "The delivery id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "202": {
            "description": "One event on its way to the webhook, retried with backoff until delivered or dead.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "deliveryId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "event": {
                      "type": "string",
                      "enum": [
                        "delivered",
                        "bounced",
                        "deferred",
                        "spam_complaint",
                        "unsubscribed",
                        "cap_warning",
                        "cap_reached",
                        "inbound"
                      ]
                    },
                    "messageId": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Null for an event about usage rather than a message."
                    },
                    "inboundMessageId": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The received message an inbound event is about; null for every other event."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "delivered",
                        "dead"
                      ],
                      "description": "pending is waiting for its next attempt; dead gave up and can be replayed."
                    },
                    "attempts": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "nextAttemptAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the next attempt is due, while pending."
                    },
                    "lastStatusCode": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "The HTTP status the endpoint last answered."
                    },
                    "lastError": {
                      "description": "Why the last attempt failed, when it did.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "deliveredAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    }
                  },
                  "required": [
                    "deliveryId",
                    "event",
                    "messageId",
                    "inboundMessageId",
                    "status",
                    "attempts",
                    "nextAttemptAt",
                    "lastStatusCode",
                    "lastError",
                    "deliveredAt",
                    "createdAt"
                  ],
                  "additionalProperties": false,
                  "description": "One event on its way to the webhook, retried with backoff until delivered or dead."
                },
                "examples": {
                  "example": {
                    "summary": "Queued again",
                    "value": {
                      "deliveryId": "9e8d7c6b-5a4f-4e3d-9c2b-1a0f9e8d7c60",
                      "event": "delivered",
                      "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                      "inboundMessageId": null,
                      "status": "pending",
                      "attempts": 0,
                      "nextAttemptAt": "2026-09-15T12:05:00.000Z",
                      "lastStatusCode": 200,
                      "lastError": null,
                      "deliveredAt": null,
                      "createdAt": "2026-09-15T12:00:02.000Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such webhook or delivery of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such webhook or delivery of this server."
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{id}/secrets": {
      "post": {
        "summary": "Create a signing secret",
        "tags": [
          "Webhooks"
        ],
        "description": "Adds a second live secret to the webhook and answers its value once; it is never shown again. From then on every delivery carries one signature per live secret, the newest first, so the receiver can switch to the new secret and the old one can be deleted. A webhook holds at most two live secrets.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The webhook id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "201": {
            "description": "The new secret, its value shown this once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "secretId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "secret": {
                      "type": "string",
                      "description": "The secret itself, shown this once."
                    }
                  },
                  "required": [
                    "secretId",
                    "createdAt",
                    "secret"
                  ],
                  "additionalProperties": false,
                  "description": "The new secret, its value shown this once."
                },
                "examples": {
                  "example": {
                    "summary": "A new secret",
                    "value": {
                      "secretId": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e",
                      "createdAt": "2026-09-20T12:00:00.000Z",
                      "secret": "whsec_0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such webhook of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such webhook of this server."
                }
              }
            }
          },
          "409": {
            "description": "The webhook already holds two live secrets: one in use and one to roll to. Delete one before creating another.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "secret_limit"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "max": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991,
                      "description": "Live secrets a webhook may hold at once."
                    }
                  },
                  "required": [
                    "error",
                    "message",
                    "max"
                  ],
                  "additionalProperties": false,
                  "description": "The webhook already holds two live secrets: one in use and one to roll to. Delete one before creating another."
                },
                "example": {
                  "error": "secret_limit",
                  "message": "The webhook may hold at most 2 live secrets; delete one before creating another.",
                  "max": 2
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{id}/secrets/{secretId}": {
      "delete": {
        "summary": "Delete a signing secret",
        "tags": [
          "Webhooks"
        ],
        "description": "Deliveries are no longer signed with it from the next one on. The last live secret of a webhook cannot be deleted, so its deliveries always carry a signature.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The webhook id."
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "secretId",
            "required": true,
            "description": "The secret id."
          }
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "204": {
            "description": "Removed. The body is empty."
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such webhook or secret of this server.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such webhook or secret of this server."
                }
              }
            }
          },
          "409": {
            "description": "The only live secret of a webhook cannot be deleted; create another first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "last_secret"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The only live secret of a webhook cannot be deleted; create another first."
                }
              }
            }
          }
        }
      }
    },
    "/v1/erasures": {
      "post": {
        "summary": "Erase a person",
        "tags": [
          "Erasures"
        ],
        "description": "Erases one person's data from every server of the account, as a request under the right to erasure asks. The content of every message to or from the address, sent and received, is deleted, and the address becomes a pseudonym in the message log. The answer is the pending erasure; Sendora carries it out within a minute, and reading it by its id shows the outcome. Erasing an address again changes nothing more. It blocks nothing: later mail to or from the address is sent and received as before.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "address": {
                    "type": "string",
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
                    "description": "The person's e-mail address."
                  }
                },
                "required": [
                  "address"
                ]
              },
              "examples": {
                "example": {
                  "summary": "A person to erase",
                  "value": {
                    "address": "anna@example.com"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "202": {
            "description": "A request to erase one person's data from the account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "erasureId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "done"
                      ],
                      "description": "pending until Sendora has erased the person, done after."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "completedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the erasure was done; null while pending."
                    },
                    "pseudonym": {
                      "description": "What now stands where the address was written in the message log; null while pending.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "messages": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Sent messages to the address whose content was deleted; null while pending."
                    },
                    "receivedMessages": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Received messages from, naming or to the address whose content was deleted; null while pending."
                    }
                  },
                  "required": [
                    "erasureId",
                    "status",
                    "createdAt",
                    "completedAt",
                    "pseudonym",
                    "messages",
                    "receivedMessages"
                  ],
                  "additionalProperties": false,
                  "description": "A request to erase one person's data from the account."
                },
                "examples": {
                  "example": {
                    "summary": "A pending erasure",
                    "value": {
                      "erasureId": "6f1d2c3b-4a5e-4f60-8b7a-9c8d7e6f5a41",
                      "status": "pending",
                      "createdAt": "2026-10-04T12:00:00.000Z",
                      "completedAt": null,
                      "pseudonym": null,
                      "messages": null,
                      "receivedMessages": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/erasures/{id}": {
      "get": {
        "summary": "Read an erasure",
        "tags": [
          "Erasures"
        ],
        "description": "The erasure and, once it is done, its outcome. A done erasure can be read for 30 days.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The erasure id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "A request to erase one person's data from the account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "erasureId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "done"
                      ],
                      "description": "pending until Sendora has erased the person, done after."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "completedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the erasure was done; null while pending."
                    },
                    "pseudonym": {
                      "description": "What now stands where the address was written in the message log; null while pending.",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "messages": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Sent messages to the address whose content was deleted; null while pending."
                    },
                    "receivedMessages": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "Received messages from, naming or to the address whose content was deleted; null while pending."
                    }
                  },
                  "required": [
                    "erasureId",
                    "status",
                    "createdAt",
                    "completedAt",
                    "pseudonym",
                    "messages",
                    "receivedMessages"
                  ],
                  "additionalProperties": false,
                  "description": "A request to erase one person's data from the account."
                },
                "examples": {
                  "example": {
                    "summary": "A done erasure",
                    "value": {
                      "erasureId": "6f1d2c3b-4a5e-4f60-8b7a-9c8d7e6f5a41",
                      "status": "done",
                      "createdAt": "2026-10-04T12:00:00.000Z",
                      "completedAt": "2026-10-04T12:00:08.000Z",
                      "pseudonym": "erased:3f7a9c1e5b2d8f4a6c0e9b7d5f3a1c8e6b4d2f0a9c7e5b3d1f8a6c4e2b0d9f7a",
                      "messages": 3,
                      "receivedMessages": 1
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such erasure of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such erasure of this account."
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains": {
      "post": {
        "summary": "Add a sending domain",
        "tags": [
          "Domains"
        ],
        "description": "Creates the domain with its own DKIM key and answers the two DNS records to add: a CNAME for the return path and a TXT record for the DKIM key. The domain may send once both records are seen, which Sendora checks on its own and on request. Domains belong to the account: every server sends from them, and an account key manages them; a server key cannot.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "domain": {
                    "type": "string",
                    "description": "The domain mail is sent from, such as example.se; lower-cased and IDNA-encoded."
                  }
                },
                "required": [
                  "domain"
                ]
              },
              "examples": {
                "example": {
                  "summary": "A domain",
                  "value": {
                    "domain": "example.se"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "201": {
            "description": "A sending domain and the two records it needs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domainId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "domain": {
                      "type": "string"
                    },
                    "verified": {
                      "type": "boolean",
                      "description": "True while both records count as found; only then may mail go out. A lookup that fails at the resolver never changes it, and a record found missing on a verified domain starts a 24-hour warning (failingSince) through which the domain stays verified."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "lastCheckedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the records were last looked up."
                    },
                    "failingSince": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When a check first found a record of this verified domain missing or wrong. Mail keeps going out, the records are looked up hourly, and the first check 24 hours after this that still misses one ends the verification. Null unless the domain is verified and in that warning; verified and each record tell the rest."
                    },
                    "returnPath": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "CNAME"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The return-path record, which also satisfies SPF."
                    },
                    "dkim": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "TXT"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The DKIM public key record."
                    }
                  },
                  "required": [
                    "domainId",
                    "domain",
                    "verified",
                    "createdAt",
                    "lastCheckedAt",
                    "failingSince",
                    "returnPath",
                    "dkim"
                  ],
                  "additionalProperties": false,
                  "description": "A sending domain and the two records it needs."
                },
                "examples": {
                  "example": {
                    "summary": "A new domain",
                    "value": {
                      "domainId": "0d7f6a1e-4c0b-4b7e-9d3c-2a1f5e8b9c01",
                      "domain": "example.se",
                      "verified": false,
                      "createdAt": "2026-09-15T12:00:00.000Z",
                      "lastCheckedAt": null,
                      "failingSince": null,
                      "returnPath": {
                        "type": "CNAME",
                        "host": "sendora-bounces.example.se",
                        "value": "bounces.sendora.se",
                        "verified": false,
                        "verifiedAt": null
                      },
                      "dkim": {
                        "type": "TXT",
                        "host": "s1._domainkey.example.se",
                        "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...",
                        "verified": false,
                        "verifiedAt": null
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body, the query or a header does not match what the route takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "invalid_request"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    },
                    "issues": {
                      "description": "One entry per invalid field; absent when a header is wrong.",
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "path": {
                            "type": "string",
                            "description": "The field, dotted, such as to.0.email; empty when the whole body is wrong."
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "path",
                          "message"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The body, the query or a header does not match what the route takes."
                },
                "example": {
                  "error": "invalid_request",
                  "message": "The request is invalid: to.0: Invalid email address",
                  "issues": [
                    {
                      "path": "to.0",
                      "message": "Invalid email address"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "409": {
            "description": "The account already has that domain.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "domain_exists"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "domainId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "description": "The id of the domain the account already has."
                    }
                  },
                  "required": [
                    "error",
                    "message",
                    "domainId"
                  ],
                  "additionalProperties": false,
                  "description": "The account already has that domain."
                },
                "example": {
                  "error": "domain_exists",
                  "message": "Your account already has that domain.",
                  "domainId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                }
              }
            }
          }
        }
      },
      "get": {
        "summary": "List the sending domains",
        "tags": [
          "Domains"
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Every sending domain of the account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domains": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "domainId": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "domain": {
                            "type": "string"
                          },
                          "verified": {
                            "type": "boolean",
                            "description": "True while both records count as found; only then may mail go out. A lookup that fails at the resolver never changes it, and a record found missing on a verified domain starts a 24-hour warning (failingSince) through which the domain stays verified."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "lastCheckedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When the records were last looked up."
                          },
                          "failingSince": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When a check first found a record of this verified domain missing or wrong. Mail keeps going out, the records are looked up hourly, and the first check 24 hours after this that still misses one ends the verification. Null unless the domain is verified and in that warning; verified and each record tell the rest."
                          },
                          "returnPath": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "enum": [
                                  "CNAME"
                                ]
                              },
                              "host": {
                                "type": "string",
                                "description": "The name to create the record under."
                              },
                              "value": {
                                "type": "string",
                                "description": "The value the record must hold."
                              },
                              "verified": {
                                "type": "boolean"
                              },
                              "verifiedAt": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "format": "date-time",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "type",
                              "host",
                              "value",
                              "verified",
                              "verifiedAt"
                            ],
                            "additionalProperties": false,
                            "description": "The return-path record, which also satisfies SPF."
                          },
                          "dkim": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "enum": [
                                  "TXT"
                                ]
                              },
                              "host": {
                                "type": "string",
                                "description": "The name to create the record under."
                              },
                              "value": {
                                "type": "string",
                                "description": "The value the record must hold."
                              },
                              "verified": {
                                "type": "boolean"
                              },
                              "verifiedAt": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "format": "date-time",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "type",
                              "host",
                              "value",
                              "verified",
                              "verifiedAt"
                            ],
                            "additionalProperties": false,
                            "description": "The DKIM public key record."
                          }
                        },
                        "required": [
                          "domainId",
                          "domain",
                          "verified",
                          "createdAt",
                          "lastCheckedAt",
                          "failingSince",
                          "returnPath",
                          "dkim"
                        ],
                        "additionalProperties": false,
                        "description": "A sending domain and the two records it needs."
                      }
                    }
                  },
                  "required": [
                    "domains"
                  ],
                  "additionalProperties": false,
                  "description": "Every sending domain of the account."
                },
                "examples": {
                  "example": {
                    "summary": "One domain",
                    "value": {
                      "domains": [
                        {
                          "domainId": "0d7f6a1e-4c0b-4b7e-9d3c-2a1f5e8b9c01",
                          "domain": "example.se",
                          "verified": false,
                          "createdAt": "2026-09-15T12:00:00.000Z",
                          "lastCheckedAt": null,
                          "failingSince": null,
                          "returnPath": {
                            "type": "CNAME",
                            "host": "sendora-bounces.example.se",
                            "value": "bounces.sendora.se",
                            "verified": false,
                            "verifiedAt": null
                          },
                          "dkim": {
                            "type": "TXT",
                            "host": "s1._domainkey.example.se",
                            "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...",
                            "verified": false,
                            "verifiedAt": null
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains/{id}": {
      "get": {
        "summary": "Read a sending domain",
        "tags": [
          "Domains"
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The domain id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "A sending domain and the two records it needs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domainId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "domain": {
                      "type": "string"
                    },
                    "verified": {
                      "type": "boolean",
                      "description": "True while both records count as found; only then may mail go out. A lookup that fails at the resolver never changes it, and a record found missing on a verified domain starts a 24-hour warning (failingSince) through which the domain stays verified."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "lastCheckedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the records were last looked up."
                    },
                    "failingSince": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When a check first found a record of this verified domain missing or wrong. Mail keeps going out, the records are looked up hourly, and the first check 24 hours after this that still misses one ends the verification. Null unless the domain is verified and in that warning; verified and each record tell the rest."
                    },
                    "returnPath": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "CNAME"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The return-path record, which also satisfies SPF."
                    },
                    "dkim": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "TXT"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The DKIM public key record."
                    }
                  },
                  "required": [
                    "domainId",
                    "domain",
                    "verified",
                    "createdAt",
                    "lastCheckedAt",
                    "failingSince",
                    "returnPath",
                    "dkim"
                  ],
                  "additionalProperties": false,
                  "description": "A sending domain and the two records it needs."
                },
                "examples": {
                  "example": {
                    "summary": "A domain",
                    "value": {
                      "domainId": "0d7f6a1e-4c0b-4b7e-9d3c-2a1f5e8b9c01",
                      "domain": "example.se",
                      "verified": false,
                      "createdAt": "2026-09-15T12:00:00.000Z",
                      "lastCheckedAt": null,
                      "failingSince": null,
                      "returnPath": {
                        "type": "CNAME",
                        "host": "sendora-bounces.example.se",
                        "value": "bounces.sendora.se",
                        "verified": false,
                        "verifiedAt": null
                      },
                      "dkim": {
                        "type": "TXT",
                        "host": "s1._domainkey.example.se",
                        "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...",
                        "verified": false,
                        "verifiedAt": null
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such domain of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such domain of this account."
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Remove a sending domain",
        "tags": [
          "Domains"
        ],
        "description": "Mail from the domain is refused from then on; its DKIM key is gone.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The domain id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "204": {
            "description": "Removed. The body is empty."
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such domain of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such domain of this account."
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains/{id}/verify": {
      "post": {
        "summary": "Check the records now",
        "tags": [
          "Domains"
        ],
        "description": "Looks both records up at once and records the result; the answer carries the domain as it stands and what each lookup found. A lookup that fails at the resolver changes nothing. A check that begins a verified domain's 24-hour warning or ends its verification mails the account's administrators, as Sendora's own checks do.",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The domain id."
          }
        ],
        "security": [
          {
            "accountToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "The domain as it stands, with what each lookup found.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "domainId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "domain": {
                      "type": "string"
                    },
                    "verified": {
                      "type": "boolean",
                      "description": "True while both records count as found; only then may mail go out. A lookup that fails at the resolver never changes it, and a record found missing on a verified domain starts a 24-hour warning (failingSince) through which the domain stays verified."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "lastCheckedAt": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When the records were last looked up."
                    },
                    "failingSince": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "When a check first found a record of this verified domain missing or wrong. Mail keeps going out, the records are looked up hourly, and the first check 24 hours after this that still misses one ends the verification. Null unless the domain is verified and in that warning; verified and each record tell the rest."
                    },
                    "returnPath": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "CNAME"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The return-path record, which also satisfies SPF."
                    },
                    "dkim": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "TXT"
                          ]
                        },
                        "host": {
                          "type": "string",
                          "description": "The name to create the record under."
                        },
                        "value": {
                          "type": "string",
                          "description": "The value the record must hold."
                        },
                        "verified": {
                          "type": "boolean"
                        },
                        "verifiedAt": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "host",
                        "value",
                        "verified",
                        "verifiedAt"
                      ],
                      "additionalProperties": false,
                      "description": "The DKIM public key record."
                    },
                    "check": {
                      "type": "object",
                      "properties": {
                        "returnPath": {
                          "type": "string",
                          "enum": [
                            "ok",
                            "missing",
                            "mismatch",
                            "dns_error"
                          ],
                          "description": "dns_error is a resolver failure, such as a DNSSEC problem or a timeout, not an absent record."
                        },
                        "dkim": {
                          "type": "string",
                          "enum": [
                            "ok",
                            "missing",
                            "mismatch",
                            "dns_error"
                          ],
                          "description": "dns_error is a resolver failure, such as a DNSSEC problem or a timeout, not an absent record."
                        }
                      },
                      "required": [
                        "returnPath",
                        "dkim"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "domainId",
                    "domain",
                    "verified",
                    "createdAt",
                    "lastCheckedAt",
                    "failingSince",
                    "returnPath",
                    "dkim",
                    "check"
                  ],
                  "additionalProperties": false,
                  "description": "The domain as it stands, with what each lookup found."
                },
                "examples": {
                  "example": {
                    "summary": "Records still missing",
                    "value": {
                      "domainId": "0d7f6a1e-4c0b-4b7e-9d3c-2a1f5e8b9c01",
                      "domain": "example.se",
                      "verified": false,
                      "createdAt": "2026-09-15T12:00:00.000Z",
                      "lastCheckedAt": null,
                      "failingSince": null,
                      "returnPath": {
                        "type": "CNAME",
                        "host": "sendora-bounces.example.se",
                        "value": "bounces.sendora.se",
                        "verified": false,
                        "verifiedAt": null
                      },
                      "dkim": {
                        "type": "TXT",
                        "host": "s1._domainkey.example.se",
                        "value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...",
                        "verified": false,
                        "verifiedAt": null
                      },
                      "check": {
                        "returnPath": "missing",
                        "dkim": "missing"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "The key is missing, malformed or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "unauthorized"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is missing, malformed or revoked."
                }
              }
            }
          },
          "403": {
            "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "wrong_token_kind"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "The key is of the other kind: a server key (sk_) where an account key (ak_) is needed, or the reverse. The message names the kind the operation takes."
                }
              }
            }
          },
          "404": {
            "description": "No such domain of this account.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "not_found"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "description": "What went wrong, for a person to read."
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ],
                  "additionalProperties": false,
                  "description": "No such domain of this account."
                }
              }
            }
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "https://api.sendora.se"
    }
  ],
  "webhooks": {
    "delivered": {
      "post": {
        "tags": [
          "Message events"
        ],
        "summary": "A message was delivered",
        "description": "The receiver accepted the message for the recipient.",
        "parameters": [
          {
            "name": "Sendora-Signature",
            "in": "header",
            "required": true,
            "description": "`t=` the Unix time of sending, then `v1=` an HMAC-SHA256 over `<t>.<body>` for each live secret of the webhook, the newest first. Verify one before you trust the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Event",
            "in": "header",
            "required": true,
            "description": "The event, the same as `event` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery, the same as `id` in the body and on every retry of it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "description": "`Sendora-Webhooks/1`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "The delivery's id. A delivery may arrive more than once, so key your handling on it."
                  },
                  "attempt": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "The attempt number, from 1."
                  },
                  "messageId": {
                    "type": "string",
                    "description": "The message the event is about."
                  },
                  "recipient": {
                    "type": "string",
                    "description": "The recipient the event is about."
                  },
                  "occurredAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "When it happened."
                  },
                  "serverId": {
                    "type": "string",
                    "description": "The server the message was sent from."
                  },
                  "streamId": {
                    "type": "string",
                    "description": "The stream the message went on."
                  },
                  "broadcastId": {
                    "description": "The broadcast the message belongs to; null for a message sent on its own.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "tag": {
                    "description": "The tag you sent with the message.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "The metadata you sent with the message."
                  },
                  "test": {
                    "type": "boolean",
                    "description": "True for a test server's message: the event was simulated and nothing was sent."
                  },
                  "event": {
                    "type": "string",
                    "const": "delivered"
                  },
                  "details": {
                    "type": "object",
                    "properties": {
                      "code": {
                        "anyOf": [
                          {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "The SMTP status code the receiver answered; null when it gave none."
                      },
                      "response": {
                        "description": "The receiver's response text.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "code",
                      "response"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "attempt",
                  "messageId",
                  "recipient",
                  "occurredAt",
                  "serverId",
                  "streamId",
                  "broadcastId",
                  "tag",
                  "metadata",
                  "test",
                  "event",
                  "details"
                ],
                "additionalProperties": false,
                "description": "The receiver accepted the message for the recipient.",
                "examples": [
                  {
                    "id": "9b2f4c1e-7a3d-4e5f-8c6b-1d2e3f4a5b6c",
                    "attempt": 1,
                    "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                    "recipient": "anna@example.com",
                    "occurredAt": "2026-09-15T12:00:03.000Z",
                    "serverId": "0f8a1b2c-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
                    "streamId": "3d1a2b4c-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                    "broadcastId": null,
                    "tag": "invoice",
                    "metadata": {
                      "invoiceId": "2026-0912"
                    },
                    "test": false,
                    "event": "delivered",
                    "details": {
                      "code": 250,
                      "response": "2.0.0 OK"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledges the delivery. Any other answer, or none within 10 seconds, is retried."
          }
        }
      }
    },
    "bounced": {
      "post": {
        "tags": [
          "Message events"
        ],
        "summary": "A message bounced",
        "description": "The receiver refused the message for good, or Sendora gave up; the recipient is suppressed when `hard`.",
        "parameters": [
          {
            "name": "Sendora-Signature",
            "in": "header",
            "required": true,
            "description": "`t=` the Unix time of sending, then `v1=` an HMAC-SHA256 over `<t>.<body>` for each live secret of the webhook, the newest first. Verify one before you trust the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Event",
            "in": "header",
            "required": true,
            "description": "The event, the same as `event` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery, the same as `id` in the body and on every retry of it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "description": "`Sendora-Webhooks/1`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "The delivery's id. A delivery may arrive more than once, so key your handling on it."
                  },
                  "attempt": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "The attempt number, from 1."
                  },
                  "messageId": {
                    "type": "string",
                    "description": "The message the event is about."
                  },
                  "recipient": {
                    "type": "string",
                    "description": "The recipient the event is about."
                  },
                  "occurredAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "When it happened."
                  },
                  "serverId": {
                    "type": "string",
                    "description": "The server the message was sent from."
                  },
                  "streamId": {
                    "type": "string",
                    "description": "The stream the message went on."
                  },
                  "broadcastId": {
                    "description": "The broadcast the message belongs to; null for a message sent on its own.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "tag": {
                    "description": "The tag you sent with the message.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "The metadata you sent with the message."
                  },
                  "test": {
                    "type": "boolean",
                    "description": "True for a test server's message: the event was simulated and nothing was sent."
                  },
                  "event": {
                    "type": "string",
                    "const": "bounced"
                  },
                  "details": {
                    "type": "object",
                    "properties": {
                      "code": {
                        "anyOf": [
                          {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "The SMTP status code the receiver answered; null when it gave none."
                      },
                      "response": {
                        "description": "The receiver's response text.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "classification": {
                        "description": "How the bounce was classified, such as InvalidRecipient.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "hard": {
                        "type": "boolean",
                        "description": "True when the address is now on the suppression list."
                      },
                      "expired": {
                        "type": "boolean",
                        "description": "True when the message expired after repeated deferrals rather than being refused."
                      }
                    },
                    "required": [
                      "code",
                      "response",
                      "classification",
                      "hard",
                      "expired"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "attempt",
                  "messageId",
                  "recipient",
                  "occurredAt",
                  "serverId",
                  "streamId",
                  "broadcastId",
                  "tag",
                  "metadata",
                  "test",
                  "event",
                  "details"
                ],
                "additionalProperties": false,
                "description": "The receiver refused the message for good, or Sendora gave up; the recipient is suppressed when `hard`.",
                "examples": [
                  {
                    "id": "9b2f4c1e-7a3d-4e5f-8c6b-1d2e3f4a5b6c",
                    "attempt": 1,
                    "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                    "recipient": "anna@example.com",
                    "occurredAt": "2026-09-15T12:00:03.000Z",
                    "serverId": "0f8a1b2c-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
                    "streamId": "3d1a2b4c-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                    "broadcastId": null,
                    "tag": "invoice",
                    "metadata": {
                      "invoiceId": "2026-0912"
                    },
                    "test": false,
                    "event": "bounced",
                    "details": {
                      "code": 550,
                      "response": "5.1.1 The email account that you tried to reach does not exist.",
                      "classification": "InvalidRecipient",
                      "hard": true,
                      "expired": false
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledges the delivery. Any other answer, or none within 10 seconds, is retried."
          }
        }
      }
    },
    "deferred": {
      "post": {
        "tags": [
          "Message events"
        ],
        "summary": "A delivery was deferred",
        "description": "The receiver asked Sendora to try later; several may follow.",
        "parameters": [
          {
            "name": "Sendora-Signature",
            "in": "header",
            "required": true,
            "description": "`t=` the Unix time of sending, then `v1=` an HMAC-SHA256 over `<t>.<body>` for each live secret of the webhook, the newest first. Verify one before you trust the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Event",
            "in": "header",
            "required": true,
            "description": "The event, the same as `event` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery, the same as `id` in the body and on every retry of it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "description": "`Sendora-Webhooks/1`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "The delivery's id. A delivery may arrive more than once, so key your handling on it."
                  },
                  "attempt": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "The attempt number, from 1."
                  },
                  "messageId": {
                    "type": "string",
                    "description": "The message the event is about."
                  },
                  "recipient": {
                    "type": "string",
                    "description": "The recipient the event is about."
                  },
                  "occurredAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "When it happened."
                  },
                  "serverId": {
                    "type": "string",
                    "description": "The server the message was sent from."
                  },
                  "streamId": {
                    "type": "string",
                    "description": "The stream the message went on."
                  },
                  "broadcastId": {
                    "description": "The broadcast the message belongs to; null for a message sent on its own.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "tag": {
                    "description": "The tag you sent with the message.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "The metadata you sent with the message."
                  },
                  "test": {
                    "type": "boolean",
                    "description": "True for a test server's message: the event was simulated and nothing was sent."
                  },
                  "event": {
                    "type": "string",
                    "const": "deferred"
                  },
                  "details": {
                    "type": "object",
                    "properties": {
                      "code": {
                        "anyOf": [
                          {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "The SMTP status code the receiver answered; null when it gave none."
                      },
                      "response": {
                        "description": "The receiver's response text.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "code",
                      "response"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "attempt",
                  "messageId",
                  "recipient",
                  "occurredAt",
                  "serverId",
                  "streamId",
                  "broadcastId",
                  "tag",
                  "metadata",
                  "test",
                  "event",
                  "details"
                ],
                "additionalProperties": false,
                "description": "The receiver asked Sendora to try later; several may follow.",
                "examples": [
                  {
                    "id": "9b2f4c1e-7a3d-4e5f-8c6b-1d2e3f4a5b6c",
                    "attempt": 1,
                    "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                    "recipient": "anna@example.com",
                    "occurredAt": "2026-09-15T12:00:03.000Z",
                    "serverId": "0f8a1b2c-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
                    "streamId": "3d1a2b4c-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                    "broadcastId": null,
                    "tag": "invoice",
                    "metadata": {
                      "invoiceId": "2026-0912"
                    },
                    "test": false,
                    "event": "deferred",
                    "details": {
                      "code": 451,
                      "response": "4.7.1 Greylisted, try again later"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledges the delivery. Any other answer, or none within 10 seconds, is retried."
          }
        }
      }
    },
    "spam_complaint": {
      "post": {
        "tags": [
          "Message events"
        ],
        "summary": "A recipient complained",
        "description": "The recipient reported the message as spam; only Sendora support lifts that suppression.",
        "parameters": [
          {
            "name": "Sendora-Signature",
            "in": "header",
            "required": true,
            "description": "`t=` the Unix time of sending, then `v1=` an HMAC-SHA256 over `<t>.<body>` for each live secret of the webhook, the newest first. Verify one before you trust the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Event",
            "in": "header",
            "required": true,
            "description": "The event, the same as `event` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery, the same as `id` in the body and on every retry of it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "description": "`Sendora-Webhooks/1`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "The delivery's id. A delivery may arrive more than once, so key your handling on it."
                  },
                  "attempt": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "The attempt number, from 1."
                  },
                  "messageId": {
                    "type": "string",
                    "description": "The message the event is about."
                  },
                  "recipient": {
                    "type": "string",
                    "description": "The recipient the event is about."
                  },
                  "occurredAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "When it happened."
                  },
                  "serverId": {
                    "type": "string",
                    "description": "The server the message was sent from."
                  },
                  "streamId": {
                    "type": "string",
                    "description": "The stream the message went on."
                  },
                  "broadcastId": {
                    "description": "The broadcast the message belongs to; null for a message sent on its own.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "tag": {
                    "description": "The tag you sent with the message.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "The metadata you sent with the message."
                  },
                  "test": {
                    "type": "boolean",
                    "description": "True for a test server's message: the event was simulated and nothing was sent."
                  },
                  "event": {
                    "type": "string",
                    "const": "spam_complaint"
                  },
                  "details": {
                    "type": "object",
                    "properties": {
                      "feedbackType": {
                        "description": "The feedback type the receiver reported, such as abuse.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "feedbackType"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "attempt",
                  "messageId",
                  "recipient",
                  "occurredAt",
                  "serverId",
                  "streamId",
                  "broadcastId",
                  "tag",
                  "metadata",
                  "test",
                  "event",
                  "details"
                ],
                "additionalProperties": false,
                "description": "The recipient reported the message as spam; only Sendora support lifts that suppression.",
                "examples": [
                  {
                    "id": "9b2f4c1e-7a3d-4e5f-8c6b-1d2e3f4a5b6c",
                    "attempt": 1,
                    "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                    "recipient": "anna@example.com",
                    "occurredAt": "2026-09-15T12:00:03.000Z",
                    "serverId": "0f8a1b2c-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
                    "streamId": "3d1a2b4c-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                    "broadcastId": null,
                    "tag": "invoice",
                    "metadata": {
                      "invoiceId": "2026-0912"
                    },
                    "test": false,
                    "event": "spam_complaint",
                    "details": {
                      "feedbackType": "abuse"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledges the delivery. Any other answer, or none within 10 seconds, is retried."
          }
        }
      }
    },
    "unsubscribed": {
      "post": {
        "tags": [
          "Message events"
        ],
        "summary": "A recipient unsubscribed",
        "description": "The recipient unsubscribed through the link or their mail client's one-click button; only Sendora support lifts that suppression.",
        "parameters": [
          {
            "name": "Sendora-Signature",
            "in": "header",
            "required": true,
            "description": "`t=` the Unix time of sending, then `v1=` an HMAC-SHA256 over `<t>.<body>` for each live secret of the webhook, the newest first. Verify one before you trust the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Event",
            "in": "header",
            "required": true,
            "description": "The event, the same as `event` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery, the same as `id` in the body and on every retry of it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "description": "`Sendora-Webhooks/1`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "The delivery's id. A delivery may arrive more than once, so key your handling on it."
                  },
                  "attempt": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "The attempt number, from 1."
                  },
                  "messageId": {
                    "type": "string",
                    "description": "The message the event is about."
                  },
                  "recipient": {
                    "type": "string",
                    "description": "The recipient the event is about."
                  },
                  "occurredAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "When it happened."
                  },
                  "serverId": {
                    "type": "string",
                    "description": "The server the message was sent from."
                  },
                  "streamId": {
                    "type": "string",
                    "description": "The stream the message went on."
                  },
                  "broadcastId": {
                    "description": "The broadcast the message belongs to; null for a message sent on its own.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "tag": {
                    "description": "The tag you sent with the message.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "metadata": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "The metadata you sent with the message."
                  },
                  "test": {
                    "type": "boolean",
                    "description": "True for a test server's message: the event was simulated and nothing was sent."
                  },
                  "event": {
                    "type": "string",
                    "const": "unsubscribed"
                  },
                  "details": {
                    "type": "object",
                    "properties": {
                      "source": {
                        "type": "string",
                        "enum": [
                          "link",
                          "one_click"
                        ],
                        "description": "`link` for the page's button, `one_click` for a mail client's request."
                      }
                    },
                    "required": [
                      "source"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "attempt",
                  "messageId",
                  "recipient",
                  "occurredAt",
                  "serverId",
                  "streamId",
                  "broadcastId",
                  "tag",
                  "metadata",
                  "test",
                  "event",
                  "details"
                ],
                "additionalProperties": false,
                "description": "The recipient unsubscribed through the link or their mail client's one-click button; only Sendora support lifts that suppression.",
                "examples": [
                  {
                    "id": "9b2f4c1e-7a3d-4e5f-8c6b-1d2e3f4a5b6c",
                    "attempt": 1,
                    "messageId": "5f432ffd-c005-499b-aa3a-5b8a088ea20e",
                    "recipient": "anna@example.com",
                    "occurredAt": "2026-09-15T12:00:03.000Z",
                    "serverId": "0f8a1b2c-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
                    "streamId": "3d1a2b4c-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                    "broadcastId": "2c4e6a8b-0d1f-4a3b-8c5d-7e9f1a3b5c7d",
                    "tag": "newsletter",
                    "metadata": {},
                    "test": false,
                    "event": "unsubscribed",
                    "details": {
                      "source": "one_click"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledges the delivery. Any other answer, or none within 10 seconds, is retried."
          }
        }
      }
    },
    "cap_warning": {
      "post": {
        "tags": [
          "The monthly cap"
        ],
        "summary": "The monthly cap is nearly used",
        "description": "80 percent of the monthly cap is used.",
        "parameters": [
          {
            "name": "Sendora-Signature",
            "in": "header",
            "required": true,
            "description": "`t=` the Unix time of sending, then `v1=` an HMAC-SHA256 over `<t>.<body>` for each live secret of the webhook, the newest first. Verify one before you trust the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Event",
            "in": "header",
            "required": true,
            "description": "The event, the same as `event` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery, the same as `id` in the body and on every retry of it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "description": "`Sendora-Webhooks/1`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "The delivery's id. A delivery may arrive more than once, so key your handling on it."
                  },
                  "attempt": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "The attempt number, from 1."
                  },
                  "scope": {
                    "type": "string",
                    "enum": [
                      "account",
                      "server",
                      "test"
                    ],
                    "description": "Whose cap it is: `account` for the account's, `server` for a server's own, `test` for the cap the account's test servers share."
                  },
                  "serverId": {
                    "description": "The server whose cap it is; null for the account's or the test servers' cap.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "cap": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Emails the scope may send in the month."
                  },
                  "used": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Emails sent in the month so far."
                  },
                  "periodStart": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "The month the counts are for: its first moment, in UTC."
                  },
                  "periodEnd": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "The first moment of the next month, in UTC."
                  },
                  "occurredAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "When it happened."
                  },
                  "event": {
                    "type": "string",
                    "const": "cap_warning"
                  }
                },
                "required": [
                  "id",
                  "attempt",
                  "scope",
                  "serverId",
                  "cap",
                  "used",
                  "periodStart",
                  "periodEnd",
                  "occurredAt",
                  "event"
                ],
                "additionalProperties": false,
                "description": "80 percent of the monthly cap is used.",
                "examples": [
                  {
                    "id": "4d6f8a0b-2c4e-4f6a-8b0c-2d4e6f8a0b1c",
                    "attempt": 1,
                    "scope": "account",
                    "serverId": null,
                    "cap": 50000,
                    "periodStart": "2026-09-01T00:00:00.000Z",
                    "periodEnd": "2026-10-01T00:00:00.000Z",
                    "used": 40000,
                    "occurredAt": "2026-09-24T09:30:00.000Z",
                    "event": "cap_warning"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledges the delivery. Any other answer, or none within 10 seconds, is retried."
          }
        }
      }
    },
    "cap_reached": {
      "post": {
        "tags": [
          "The monthly cap"
        ],
        "summary": "The monthly cap is used up",
        "description": "A send was refused because the monthly cap is used up.",
        "parameters": [
          {
            "name": "Sendora-Signature",
            "in": "header",
            "required": true,
            "description": "`t=` the Unix time of sending, then `v1=` an HMAC-SHA256 over `<t>.<body>` for each live secret of the webhook, the newest first. Verify one before you trust the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Event",
            "in": "header",
            "required": true,
            "description": "The event, the same as `event` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery, the same as `id` in the body and on every retry of it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "description": "`Sendora-Webhooks/1`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "The delivery's id. A delivery may arrive more than once, so key your handling on it."
                  },
                  "attempt": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "The attempt number, from 1."
                  },
                  "scope": {
                    "type": "string",
                    "enum": [
                      "account",
                      "server",
                      "test"
                    ],
                    "description": "Whose cap it is: `account` for the account's, `server` for a server's own, `test` for the cap the account's test servers share."
                  },
                  "serverId": {
                    "description": "The server whose cap it is; null for the account's or the test servers' cap.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "cap": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Emails the scope may send in the month."
                  },
                  "used": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Emails sent in the month so far."
                  },
                  "periodStart": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "The month the counts are for: its first moment, in UTC."
                  },
                  "periodEnd": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "The first moment of the next month, in UTC."
                  },
                  "occurredAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                    "description": "When it happened."
                  },
                  "event": {
                    "type": "string",
                    "const": "cap_reached"
                  }
                },
                "required": [
                  "id",
                  "attempt",
                  "scope",
                  "serverId",
                  "cap",
                  "used",
                  "periodStart",
                  "periodEnd",
                  "occurredAt",
                  "event"
                ],
                "additionalProperties": false,
                "description": "A send was refused because the monthly cap is used up.",
                "examples": [
                  {
                    "id": "4d6f8a0b-2c4e-4f6a-8b0c-2d4e6f8a0b1c",
                    "attempt": 1,
                    "scope": "account",
                    "serverId": null,
                    "cap": 50000,
                    "periodStart": "2026-09-01T00:00:00.000Z",
                    "periodEnd": "2026-10-01T00:00:00.000Z",
                    "used": 50000,
                    "occurredAt": "2026-09-29T16:05:00.000Z",
                    "event": "cap_reached"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledges the delivery. Any other answer, or none within 10 seconds, is retried."
          }
        }
      }
    },
    "inbound": {
      "post": {
        "tags": [
          "Received mail"
        ],
        "summary": "A message was received",
        "description": "A message was received on an inbound stream: the reference, or the reference and the message itself, as the webhook asks.",
        "parameters": [
          {
            "name": "Sendora-Signature",
            "in": "header",
            "required": true,
            "description": "`t=` the Unix time of sending, then `v1=` an HMAC-SHA256 over `<t>.<body>` for each live secret of the webhook, the newest first. Verify one before you trust the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Event",
            "in": "header",
            "required": true,
            "description": "The event, the same as `event` in the body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sendora-Delivery-Id",
            "in": "header",
            "required": true,
            "description": "The delivery, the same as `id` in the body and on every retry of it.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "User-Agent",
            "in": "header",
            "required": true,
            "description": "`Sendora-Webhooks/1`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The delivery's id. A delivery may arrive more than once, so key your handling on it."
                      },
                      "attempt": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "description": "The attempt number, from 1."
                      },
                      "event": {
                        "type": "string",
                        "const": "inbound"
                      },
                      "inboundMessageId": {
                        "type": "string",
                        "description": "The received message; GET /v1/inbound/{id} reads it."
                      },
                      "serverId": {
                        "type": "string",
                        "description": "The server whose stream received it."
                      },
                      "streamId": {
                        "type": "string",
                        "description": "The inbound stream that received it."
                      },
                      "receivedAt": {
                        "type": "string",
                        "format": "date-time",
                        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                        "description": "When the message was accepted from the sending server."
                      },
                      "envelopeRecipient": {
                        "type": "string",
                        "description": "The address of yours the message was sent to."
                      },
                      "mailboxHash": {
                        "description": "The text after `+` in the local part of that address, when the sender used one.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "sizeBytes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "description": "The size of the message as received, in bytes."
                      },
                      "attachmentCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "hasText": {
                        "type": "boolean"
                      },
                      "hasHtml": {
                        "type": "boolean"
                      },
                      "authentication": {
                        "type": "object",
                        "properties": {
                          "spf": {
                            "type": "string",
                            "enum": [
                              "pass",
                              "fail",
                              "softfail",
                              "neutral",
                              "none",
                              "temperror",
                              "permerror",
                              "unchecked"
                            ],
                            "description": "SPF for the address in MAIL FROM."
                          },
                          "spfHelo": {
                            "type": "string",
                            "enum": [
                              "pass",
                              "fail",
                              "softfail",
                              "neutral",
                              "none",
                              "temperror",
                              "permerror",
                              "unchecked"
                            ],
                            "description": "SPF for the name the sending server gave in HELO."
                          },
                          "dkim": {
                            "type": "string",
                            "enum": [
                              "pass",
                              "fail",
                              "none",
                              "temperror",
                              "permerror",
                              "unchecked"
                            ]
                          },
                          "dmarc": {
                            "type": "string",
                            "enum": [
                              "pass",
                              "fail",
                              "none",
                              "temperror",
                              "permerror",
                              "unchecked"
                            ]
                          },
                          "dmarcPolicy": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "none",
                                  "quarantine",
                                  "reject"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What the sender's domain asks for; told only when DMARC failed."
                          },
                          "arc": {
                            "type": "string",
                            "enum": [
                              "none",
                              "pass",
                              "fail",
                              "unchecked"
                            ]
                          },
                          "checkedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When the checks ran; null until they have."
                          }
                        },
                        "required": [
                          "spf",
                          "spfHelo",
                          "dkim",
                          "dmarc",
                          "dmarcPolicy",
                          "arc",
                          "checkedAt"
                        ],
                        "additionalProperties": false,
                        "description": "What Sendora found when it checked the message's authentication; `unchecked` until the checks have run."
                      },
                      "parseIssue": {
                        "description": "What the parser met; null when the message parsed clean. A hard issue empties the parsed parts, and the raw message stays: `no_headers`, `header_block_too_large`, `too_many_headers`, `too_many_parts`, `nesting_too_deep`, `missing_boundary`, `decoded_too_large`, `parse_timeout`, `parser_error`. A soft issue keeps them and says what was changed or dropped: `truncated_multipart`, `too_many_attachments`, `unknown_transfer_encoding`, `undecodable_container`, `filename_sanitised`, `control_chars_stripped`, `multiple_from`, `duplicate_header`, `malformed_header_dropped`, `address_list_truncated`, `header_value_truncated`. A message with several names the hard one, or the first soft one in this order.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "id",
                      "attempt",
                      "event",
                      "inboundMessageId",
                      "serverId",
                      "streamId",
                      "receivedAt",
                      "envelopeRecipient",
                      "mailboxHash",
                      "sizeBytes",
                      "attachmentCount",
                      "hasText",
                      "hasHtml",
                      "authentication",
                      "parseIssue"
                    ],
                    "additionalProperties": false,
                    "description": "The reference to the received message, for a webhook with `inboundContent` reference.",
                    "examples": [
                      {
                        "id": "6e8a0c2e-4a6c-4e8a-8c0e-2a4c6e8a0c2e",
                        "attempt": 1,
                        "event": "inbound",
                        "inboundMessageId": "1b3d5f7a-9c1e-4b3d-8f7a-9c1e3b5d7f9a",
                        "serverId": "0f8a1b2c-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
                        "streamId": "8a0c2e4a-6c8e-4a0c-8e4a-6c8e0a2c4e6a",
                        "receivedAt": "2026-09-15T12:00:00.000Z",
                        "envelopeRecipient": "support@example.se",
                        "mailboxHash": null,
                        "sizeBytes": 18432,
                        "attachmentCount": 1,
                        "hasText": true,
                        "hasHtml": true,
                        "authentication": {
                          "spf": "pass",
                          "spfHelo": "pass",
                          "dkim": "pass",
                          "dmarc": "pass",
                          "dmarcPolicy": null,
                          "arc": "none",
                          "checkedAt": "2026-09-15T12:00:00.000Z"
                        },
                        "parseIssue": null
                      }
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The delivery's id. A delivery may arrive more than once, so key your handling on it."
                      },
                      "attempt": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "description": "The attempt number, from 1."
                      },
                      "event": {
                        "type": "string",
                        "const": "inbound"
                      },
                      "inboundMessageId": {
                        "type": "string",
                        "description": "The received message; GET /v1/inbound/{id} reads it."
                      },
                      "serverId": {
                        "type": "string",
                        "description": "The server whose stream received it."
                      },
                      "streamId": {
                        "type": "string",
                        "description": "The inbound stream that received it."
                      },
                      "receivedAt": {
                        "type": "string",
                        "format": "date-time",
                        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                        "description": "When the message was accepted from the sending server."
                      },
                      "envelopeRecipient": {
                        "type": "string",
                        "description": "The address of yours the message was sent to."
                      },
                      "mailboxHash": {
                        "description": "The text after `+` in the local part of that address, when the sender used one.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "sizeBytes": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991,
                        "description": "The size of the message as received, in bytes."
                      },
                      "attachmentCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "hasText": {
                        "type": "boolean"
                      },
                      "hasHtml": {
                        "type": "boolean"
                      },
                      "authentication": {
                        "type": "object",
                        "properties": {
                          "spf": {
                            "type": "string",
                            "enum": [
                              "pass",
                              "fail",
                              "softfail",
                              "neutral",
                              "none",
                              "temperror",
                              "permerror",
                              "unchecked"
                            ],
                            "description": "SPF for the address in MAIL FROM."
                          },
                          "spfHelo": {
                            "type": "string",
                            "enum": [
                              "pass",
                              "fail",
                              "softfail",
                              "neutral",
                              "none",
                              "temperror",
                              "permerror",
                              "unchecked"
                            ],
                            "description": "SPF for the name the sending server gave in HELO."
                          },
                          "dkim": {
                            "type": "string",
                            "enum": [
                              "pass",
                              "fail",
                              "none",
                              "temperror",
                              "permerror",
                              "unchecked"
                            ]
                          },
                          "dmarc": {
                            "type": "string",
                            "enum": [
                              "pass",
                              "fail",
                              "none",
                              "temperror",
                              "permerror",
                              "unchecked"
                            ]
                          },
                          "dmarcPolicy": {
                            "anyOf": [
                              {
                                "type": "string",
                                "enum": [
                                  "none",
                                  "quarantine",
                                  "reject"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "What the sender's domain asks for; told only when DMARC failed."
                          },
                          "arc": {
                            "type": "string",
                            "enum": [
                              "none",
                              "pass",
                              "fail",
                              "unchecked"
                            ]
                          },
                          "checkedAt": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "When the checks ran; null until they have."
                          }
                        },
                        "required": [
                          "spf",
                          "spfHelo",
                          "dkim",
                          "dmarc",
                          "dmarcPolicy",
                          "arc",
                          "checkedAt"
                        ],
                        "additionalProperties": false,
                        "description": "What Sendora found when it checked the message's authentication; `unchecked` until the checks have run."
                      },
                      "parseIssue": {
                        "description": "What the parser met; null when the message parsed clean. A hard issue empties the parsed parts, and the raw message stays: `no_headers`, `header_block_too_large`, `too_many_headers`, `too_many_parts`, `nesting_too_deep`, `missing_boundary`, `decoded_too_large`, `parse_timeout`, `parser_error`. A soft issue keeps them and says what was changed or dropped: `truncated_multipart`, `too_many_attachments`, `unknown_transfer_encoding`, `undecodable_container`, `filename_sanitised`, `control_chars_stripped`, `multiple_from`, `duplicate_header`, `malformed_header_dropped`, `address_list_truncated`, `header_value_truncated`. A message with several names the hard one, or the first soft one in this order.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "envelope": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "sender": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "sender"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "The envelope sender; null for a bounce."
                      },
                      "from": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "address": {
                                "type": "string"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "address",
                              "name"
                            ],
                            "additionalProperties": false
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "replyTo": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "address": {
                              "type": "string"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "address",
                            "name"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "to": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "address": {
                              "type": "string"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "address",
                            "name"
                          ],
                          "additionalProperties": false
                        },
                        "description": "Up to 100 entries; `toCount` is the whole number."
                      },
                      "toCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "cc": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "address": {
                              "type": "string"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "address",
                            "name"
                          ],
                          "additionalProperties": false
                        },
                        "description": "Up to 100 entries; `ccCount` is the whole number."
                      },
                      "ccCount": {
                        "type": "integer",
                        "minimum": -9007199254740991,
                        "maximum": 9007199254740991
                      },
                      "subject": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "date": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "The sender's Date header, when it was a real moment."
                      },
                      "messageIdHeader": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "inReplyTo": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "references": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "headers": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "name": {
                              "type": "string"
                            },
                            "value": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "name",
                            "value"
                          ],
                          "additionalProperties": false
                        }
                      },
                      "text": {
                        "description": "The plain-text body; null when there is none, or over 1 MiB.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "html": {
                        "description": "The HTML body; null when there is none, or over 2 MiB.",
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "attachments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "position": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991,
                              "description": "Its place among the message's attachments, from 0."
                            },
                            "name": {
                              "type": "string"
                            },
                            "contentType": {
                              "type": "string"
                            },
                            "contentId": {
                              "description": "The Content-ID an HTML body refers to with `cid:`, when it has one.",
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "size": {
                              "type": "integer",
                              "minimum": -9007199254740991,
                              "maximum": 9007199254740991
                            },
                            "inline": {
                              "type": "boolean",
                              "description": "True for a part shown in the body rather than offered as a file."
                            }
                          },
                          "required": [
                            "position",
                            "name",
                            "contentType",
                            "contentId",
                            "size",
                            "inline"
                          ],
                          "additionalProperties": false
                        },
                        "description": "Each attachment, without its bytes."
                      },
                      "contentOmitted": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "too_large",
                              "expired"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "description": "`too_large` when text or HTML was left out for size; `expired` when the content window has passed and the reference is all that remains."
                      }
                    },
                    "required": [
                      "id",
                      "attempt",
                      "event",
                      "inboundMessageId",
                      "serverId",
                      "streamId",
                      "receivedAt",
                      "envelopeRecipient",
                      "mailboxHash",
                      "sizeBytes",
                      "attachmentCount",
                      "hasText",
                      "hasHtml",
                      "authentication",
                      "parseIssue",
                      "envelope",
                      "from",
                      "replyTo",
                      "to",
                      "toCount",
                      "cc",
                      "ccCount",
                      "subject",
                      "date",
                      "messageIdHeader",
                      "inReplyTo",
                      "references",
                      "headers",
                      "text",
                      "html",
                      "attachments",
                      "contentOmitted"
                    ],
                    "additionalProperties": false,
                    "description": "The reference and the message itself, for a webhook with `inboundContent` full.",
                    "examples": [
                      {
                        "id": "6e8a0c2e-4a6c-4e8a-8c0e-2a4c6e8a0c2e",
                        "attempt": 1,
                        "event": "inbound",
                        "inboundMessageId": "1b3d5f7a-9c1e-4b3d-8f7a-9c1e3b5d7f9a",
                        "serverId": "0f8a1b2c-3d4e-4f5a-8b6c-7d8e9f0a1b2c",
                        "streamId": "8a0c2e4a-6c8e-4a0c-8e4a-6c8e0a2c4e6a",
                        "receivedAt": "2026-09-15T12:00:00.000Z",
                        "envelopeRecipient": "support@example.se",
                        "mailboxHash": null,
                        "sizeBytes": 18432,
                        "attachmentCount": 1,
                        "hasText": true,
                        "hasHtml": true,
                        "authentication": {
                          "spf": "pass",
                          "spfHelo": "pass",
                          "dkim": "pass",
                          "dmarc": "pass",
                          "dmarcPolicy": null,
                          "arc": "none",
                          "checkedAt": "2026-09-15T12:00:00.000Z"
                        },
                        "parseIssue": null,
                        "envelope": {
                          "sender": "anna@example.com"
                        },
                        "from": {
                          "address": "anna@example.com",
                          "name": "Anna Andersson"
                        },
                        "replyTo": [],
                        "to": [
                          {
                            "address": "support@example.se",
                            "name": null
                          }
                        ],
                        "toCount": 1,
                        "cc": [],
                        "ccCount": 0,
                        "subject": "A question about the invoice",
                        "date": "2026-09-15T11:59:58.000Z",
                        "messageIdHeader": "<20260915115958.a1b2@example.com>",
                        "inReplyTo": null,
                        "references": [],
                        "headers": [
                          {
                            "name": "From",
                            "value": "Anna Andersson <anna@example.com>"
                          },
                          {
                            "name": "To",
                            "value": "support@example.se"
                          },
                          {
                            "name": "Subject",
                            "value": "A question about the invoice"
                          }
                        ],
                        "text": "Hi! I have a question about the invoice for September.",
                        "html": "<p>Hi! I have a question about the invoice for September.</p>",
                        "attachments": [
                          {
                            "position": 0,
                            "name": "invoice.pdf",
                            "contentType": "application/pdf",
                            "contentId": null,
                            "size": 15360,
                            "inline": false
                          }
                        ],
                        "contentOmitted": null
                      }
                    ]
                  }
                ],
                "description": "A message was received on an inbound stream: the reference, or the reference and the message itself, as the webhook asks."
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Acknowledges the delivery. Any other answer, or none within 10 seconds, is retried."
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Sending",
      "description": "Hand messages over for delivery."
    },
    {
      "name": "Broadcasts",
      "description": "One message to many, sent as a broadcast."
    },
    {
      "name": "Messages",
      "description": "The message log and each message’s timeline."
    },
    {
      "name": "Inbound",
      "description": "The mail the server has received: the messages, their raw form and their attachments."
    },
    {
      "name": "Streams",
      "description": "The streams of the server: transactional, broadcast, and at most one inbound."
    },
    {
      "name": "Servers",
      "description": "The account’s servers and each one’s keys, under an account key: a server is created with its first key and holds up to two. GET /v1/server takes a server key and reads that key’s own server."
    },
    {
      "name": "Domains",
      "description": "Sending domains and their two DNS records, under an account key."
    },
    {
      "name": "Erasures",
      "description": "A person's data erased from every server of the account, under an account key."
    },
    {
      "name": "Suppressions",
      "description": "Addresses the server no longer sends to."
    },
    {
      "name": "Webhooks",
      "description": "Where events are posted, signed with each of the webhook’s live secrets, and every delivery of them."
    },
    {
      "name": "Keys",
      "description": "A server's own keys under one of them, up to two live at once; an account key manages them under /v1/servers/{id}/tokens, and the account's own keys are created in the dashboard."
    }
  ]
}