{
    "openapi": "3.1.0",
    "info": {
        "title": "1stlevel.tech API",
        "version": "1.2.0",
        "description": "Bearer tokens are created and revoked under /konto/api by account admins. Tokens may be scoped to one team and expire after one year when created in the UI. Solo: read only, 60 requests/minute; Trial/Team: read and write, 120/minute; Team+: 300/minute. Frozen accounts remain readable. POST requires Idempotency-Key. Outgoing messages are delivered asynchronously. Webhooks are at-least-once, may arrive out of order, and retry up to eight attempts. Verify X-1stlevel-Signature (t=<unix>,v1=<hex HMAC-SHA256 of timestamp.rawBody>), reject timestamps outside five minutes, deduplicate the event UUID. Receivers must use public HTTPS on port 443; redirects are not followed."
    },
    "servers": [
        {
            "url": "/api/v1"
        }
    ],
    "tags": [
        {
            "name": "Tickets",
            "description": "Tickets auflisten, anlegen, lesen, bearbeiten und zusammenführen."
        },
        {
            "name": "Messages",
            "description": "Eingehende Kundennachrichten erfassen und Antworten versenden."
        },
        {
            "name": "Teams",
            "description": "Teams ermitteln, die im Bereich des Tokens liegen."
        },
        {
            "name": "Attachments",
            "description": "Private Anhänge sichtbarer Nachrichten herunterladen."
        }
    ],
    "paths": {
        "/tickets": {
            "get": {
                "summary": "List tickets in the token scope",
                "operationId": "listTickets",
                "tags": ["Tickets"],
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "open",
                                "in_progress",
                                "done"
                            ]
                        }
                    },
                    {
                        "name": "requester_email",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "external_ref",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        }
                    },
                    {
                        "name": "per_page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    },
                    {
                        "name": "team",
                        "in": "query",
                        "schema": {
                            "type": "integer"
                        },
                        "description": "Further restrict results within the token team scope."
                    },
                    {
                        "name": "due_today",
                        "in": "query",
                        "schema": {
                            "type": "boolean"
                        },
                        "description": "Open tickets with follow-up date today or earlier."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Ticket"
                                            }
                                        },
                                        "links": {
                                            "type": "object"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked bearer token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Token, team, plan or account does not allow this operation.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Resource not found within the token scope.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key already used for a different method, path or raw JSON body.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed or missing/invalid Idempotency-Key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit reached. Respect Retry-After.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "summary": "Create a ticket and its first requester message",
                "operationId": "createTicket",
                "tags": ["Tickets"],
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9._:-]{1,128}$"
                        },
                        "description": "Unique per token across POST routes. Exact successful response is retained until the token is revoked. Replays include Idempotency-Replayed: true."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateTicket"
                            },
                            "example": {
                                "team": 1,
                                "requester_email": "customer@example.com",
                                "requester_name": "Ada Example",
                                "subject": "VPN login fails",
                                "body": "The login has failed since this morning.",
                                "locale": "en",
                                "external_ref": "CRM-4711"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Success",
                        "headers": {
                            "Idempotency-Replayed": {
                                "$ref": "#/components/headers/IdempotencyReplayed"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Ticket"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked bearer token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Token, team, plan or account does not allow this operation.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Resource not found within the token scope.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key already used for a different method, path or raw JSON body.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed or missing/invalid Idempotency-Key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit reached. Respect Retry-After.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/tickets/{ticketId}": {
            "parameters": [
                {
                    "name": "ticketId",
                    "in": "path",
                    "required": true,
                    "schema": {
                        "type": "integer",
                        "minimum": 1
                    }
                }
            ],
            "get": {
                "summary": "Read a ticket including public messages; internal notes are excluded",
                "operationId": "getTicket",
                "tags": ["Tickets"],
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Ticket"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked bearer token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Token, team, plan or account does not allow this operation.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Resource not found within the token scope.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key already used for a different method, path or raw JSON body.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed or missing/invalid Idempotency-Key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit reached. Respect Retry-After.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            },
            "patch": {
                "summary": "Change status, priority or assignee",
                "operationId": "updateTicket",
                "tags": ["Tickets"],
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Ticket"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked bearer token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Token, team, plan or account does not allow this operation.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Resource not found within the token scope.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key already used for a different method, path or raw JSON body.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed or missing/invalid Idempotency-Key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit reached. Respect Retry-After.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/UpdateTicket"
                            },
                            "example": {
                                "status": "in_progress",
                                "priority": "high",
                                "category": "access",
                                "due_at": "2026-09-10"
                            }
                        }
                    }
                }
            }
        },
        "/tickets/{ticketId}/messages": {
            "parameters": [
                {
                    "name": "ticketId",
                    "in": "path",
                    "required": true,
                    "schema": {
                        "type": "integer",
                        "minimum": 1
                    }
                }
            ],
            "post": {
                "summary": "Append a requester message or queue a reply",
                "operationId": "createTicketMessage",
                "tags": ["Messages"],
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[A-Za-z0-9._:-]{1,128}$"
                        },
                        "description": "Unique per token across POST routes. Exact successful response is retained until the token is revoked. Replays include Idempotency-Replayed: true."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/CreateMessage"
                            },
                            "example": {
                                "direction": "out",
                                "body": "Please try to sign in again."
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Success",
                        "headers": {
                            "Idempotency-Replayed": {
                                "$ref": "#/components/headers/IdempotencyReplayed"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Message"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked bearer token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Token, team, plan or account does not allow this operation.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Resource not found within the token scope.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key already used for a different method, path or raw JSON body.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed or missing/invalid Idempotency-Key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit reached. Respect Retry-After.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/teams": {
            "get": {
                "summary": "List teams available to the token",
                "operationId": "listTeams",
                "tags": ["Teams"],
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "page",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Success",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Team"
                                            }
                                        },
                                        "links": {
                                            "type": "object"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Missing, invalid, expired or revoked bearer token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Token, team, plan or account does not allow this operation.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Resource not found within the token scope.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key already used for a different method, path or raw JSON body.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation failed or missing/invalid Idempotency-Key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Rate limit reached. Respect Retry-After.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "schema": {
                                    "type": "integer"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/attachments/{attachmentId}": {
            "get": {
                "summary": "Download a message attachment within the token tenant and team scope; internal notes are excluded.",
                "operationId": "downloadAttachment",
                "tags": ["Attachments"],
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "attachmentId",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Private attachment download; send the bearer token to the download URL.",
                        "content": {
                            "application/octet-stream": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Invalid or absent bearer token."
                    },
                    "403": {
                        "description": "Missing tickets:read ability."
                    },
                    "404": {
                        "description": "Not found or outside the token scope."
                    },
                    "429": {
                        "description": "Token rate limit exceeded."
                    }
                }
            }
        },
        "/tickets/{ticketId}/merge": {
            "parameters": [
                {
                    "name": "ticketId",
                    "in": "path",
                    "required": true,
                    "schema": {
                        "type": "integer"
                    }
                }
            ],
            "post": {
                "summary": "Merge duplicate into a target belonging to the same team and requester email. Messages and attachments move, old status links and mail numbers remain usable.",
                "operationId": "mergeTicket",
                "tags": ["Tickets"],
                "description": "Target fields are retained; a resolved target reopens if the source was open. Repeating the same source and target has no additional effect. Both tickets must be within the token scope. The source remains as a read-only alias.",
                "security": [
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 128
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "target_id"
                                ],
                                "properties": {
                                    "target_id": {
                                        "type": "integer"
                                    }
                                }
                            },
                            "example": {
                                "target_id": 456
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Canonical target ticket",
                        "headers": {
                            "Idempotency-Replayed": {
                                "$ref": "#/components/headers/IdempotencyReplayed"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Ticket"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Invalid bearer token."
                    },
                    "403": {
                        "description": "Read-only plan, frozen account or missing write ability."
                    },
                    "404": {
                        "description": "Source or target not found in token scope."
                    },
                    "409": {
                        "description": "Source already merged elsewhere or idempotency conflict."
                    },
                    "422": {
                        "description": "Invalid target, different requester or team."
                    },
                    "429": {
                        "description": "Rate limit exceeded."
                    }
                }
            }
        }
    },
    "webhooks": {
        "ticketEvent": {
            "post": {
                "summary": "Ticket or message event delivered to a configured receiver",
                "description": "1stlevel.tech sends this request at least once and without an ordering guarantee. Verify the HMAC over the unchanged request bytes, reject timestamps outside five minutes, and deduplicate the event UUID. Any 2xx response acknowledges delivery; other results are retried up to eight attempts.",
                "operationId": "receiveTicketEvent",
                "parameters": [
                    {
                        "name": "X-1stlevel-Event-Id",
                        "in": "header",
                        "required": true,
                        "description": "Stable UUID for deduplication across delivery attempts.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "X-1stlevel-Signature",
                        "in": "header",
                        "required": true,
                        "description": "t=<Unix timestamp>,v1=<lowercase hex HMAC-SHA256 of timestamp.rawBody>.",
                        "schema": {
                            "type": "string",
                            "pattern": "^t=[0-9]+,v1=[a-f0-9]{64}$"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/Webhook"
                            }
                        }
                    }
                },
                "responses": {
                    "2XX": {
                        "description": "Event accepted by the receiver."
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer"
            }
        },
        "headers": {
            "IdempotencyReplayed": {
                "description": "Present with value true only when the stored response for this Idempotency-Key was replayed.",
                "schema": {
                    "type": "string",
                    "const": "true"
                }
            }
        },
        "schemas": {
            "Message": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "direction": {
                        "type": "string",
                        "enum": [
                            "in",
                            "out"
                        ]
                    },
                    "body": {
                        "type": "string"
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "sent_at": {
                        "anyOf": [
                            {
                                "type": "string",
                                "format": "date-time"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "delivery_status": {
                        "anyOf": [
                            {
                                "type": "string",
                                "enum": [
                                    "pending",
                                    "failed",
                                    "sent"
                                ]
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "attachments": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Attachment"
                        }
                    }
                },
                "required": [
                    "id",
                    "direction",
                    "body",
                    "created_at",
                    "sent_at",
                    "delivery_status",
                    "attachments"
                ]
            },
            "Ticket": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "number": {
                        "type": "integer"
                    },
                    "team": {
                        "type": "integer"
                    },
                    "requester_email": {
                        "type": "string",
                        "format": "email"
                    },
                    "requester_name": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "subject": {
                        "type": "string"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "open",
                            "in_progress",
                            "done"
                        ]
                    },
                    "priority": {
                        "type": "string",
                        "enum": [
                            "normal",
                            "high"
                        ]
                    },
                    "assignee_id": {
                        "anyOf": [
                            {
                                "type": "integer"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "locale": {
                        "type": "string",
                        "enum": [
                            "de",
                            "en"
                        ]
                    },
                    "external_ref": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "messages": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/Message"
                        }
                    },
                    "category": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "hardware",
                            "software",
                            "access",
                            "network",
                            "other",
                            null
                        ]
                    },
                    "due_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "Follow-up calendar date YYYY-MM-DD. Open tickets become due from this date; null clears it."
                    },
                    "merged_into_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Canonical target for a merged alias. Alias mutations return 409. GET by alias ID remains available."
                    }
                },
                "required": [
                    "id",
                    "number",
                    "team",
                    "requester_email",
                    "requester_name",
                    "subject",
                    "status",
                    "priority",
                    "category",
                    "due_at",
                    "assignee_id",
                    "locale",
                    "external_ref",
                    "created_at",
                    "updated_at",
                    "merged_into_id"
                ]
            },
            "Team": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "locale": {
                        "type": "string",
                        "enum": [
                            "de",
                            "en"
                        ]
                    }
                },
                "required": [
                    "id",
                    "name",
                    "locale"
                ]
            },
            "CreateTicket": {
                "type": "object",
                "required": [
                    "requester_email",
                    "subject",
                    "body"
                ],
                "properties": {
                    "team": {
                        "type": "integer",
                        "description": "Required unless the token is scoped to a team."
                    },
                    "requester_email": {
                        "type": "string",
                        "format": "email",
                        "maxLength": 190
                    },
                    "requester_name": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 190
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "subject": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                    },
                    "body": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100000
                    },
                    "locale": {
                        "type": "string",
                        "enum": [
                            "de",
                            "en"
                        ]
                    },
                    "external_ref": {
                        "anyOf": [
                            {
                                "type": "string",
                                "maxLength": 255
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "attachments": {
                        "type": "array",
                        "maxItems": 10,
                        "description": "10 MiB per file; 15 MiB total decoded bytes per message.",
                        "items": {
                            "$ref": "#/components/schemas/AttachmentInput"
                        }
                    }
                }
            },
            "UpdateTicket": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "string",
                        "enum": [
                            "open",
                            "in_progress",
                            "done"
                        ]
                    },
                    "priority": {
                        "type": "string",
                        "enum": [
                            "normal",
                            "high"
                        ]
                    },
                    "assignee_id": {
                        "anyOf": [
                            {
                                "type": "integer"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "category": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "hardware",
                            "software",
                            "access",
                            "network",
                            "other",
                            null
                        ]
                    },
                    "locale": {
                        "type": "string",
                        "enum": [
                            "de",
                            "en"
                        ]
                    },
                    "due_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date",
                        "description": "Follow-up calendar date YYYY-MM-DD. Open tickets become due from this date; null clears it."
                    }
                }
            },
            "CreateMessage": {
                "type": "object",
                "required": [
                    "direction",
                    "body"
                ],
                "properties": {
                    "direction": {
                        "type": "string",
                        "enum": [
                            "in",
                            "out"
                        ]
                    },
                    "body": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100000
                    },
                    "attachments": {
                        "type": "array",
                        "maxItems": 10,
                        "description": "10 MiB per file; 15 MiB total decoded bytes per message.",
                        "items": {
                            "$ref": "#/components/schemas/AttachmentInput"
                        }
                    }
                }
            },
            "Error": {
                "type": "object",
                "properties": {
                    "message": {
                        "type": "string"
                    },
                    "errors": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "Webhook": {
                "type": "object",
                "required": [
                    "id",
                    "type",
                    "created_at",
                    "data"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "ticket.created",
                            "ticket.status_changed",
                            "message.created"
                        ]
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "data": {
                        "type": "object",
                        "required": [
                            "ticket_id",
                            "merged_into_id",
                            "team_id",
                            "status",
                            "external_ref",
                            "message"
                        ],
                        "properties": {
                            "ticket_id": {
                                "type": "integer"
                            },
                            "merged_into_id": {
                                "anyOf": [
                                    {
                                        "type": "integer"
                                    },
                                    {
                                        "type": "null"
                                    }
                                ]
                            },
                            "team_id": {
                                "type": "integer"
                            },
                            "status": {
                                "type": "string",
                                "enum": [
                                    "open",
                                    "in_progress",
                                    "done"
                                ]
                            },
                            "external_ref": {
                                "anyOf": [
                                    {
                                        "type": "string"
                                    },
                                    {
                                        "type": "null"
                                    }
                                ]
                            },
                            "message": {
                                "anyOf": [
                                    {
                                        "type": "object",
                                        "required": [
                                            "id",
                                            "direction",
                                            "body"
                                        ],
                                        "properties": {
                                            "id": {
                                                "type": "integer"
                                            },
                                            "direction": {
                                                "type": "string",
                                                "enum": [
                                                    "in",
                                                    "out"
                                                ]
                                            },
                                            "body": {
                                                "type": "string"
                                            }
                                        }
                                    },
                                    {
                                        "type": "null"
                                    }
                                ]
                            }
                        }
                    }
                }
            },
            "AttachmentInput": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                    "name",
                    "content_base64"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "maxLength": 200
                    },
                    "content_base64": {
                        "type": "string",
                        "contentEncoding": "base64",
                        "maxLength": 13981016
                    }
                }
            },
            "Attachment": {
                "type": "object",
                "required": [
                    "id",
                    "name",
                    "size",
                    "mime_type",
                    "sha256",
                    "download_url"
                ],
                "properties": {
                    "id": {
                        "type": "integer"
                    },
                    "name": {
                        "type": "string"
                    },
                    "size": {
                        "type": "integer"
                    },
                    "mime_type": {
                        "type": "string"
                    },
                    "sha256": {
                        "type": "string"
                    },
                    "download_url": {
                        "type": "string",
                        "format": "uri"
                    }
                }
            }
        }
    }
}
