{
  "openapi": "3.1.0",
  "info": {
    "title": "BotPost Bot-Schnittstelle",
    "version": "0.1.0",
    "description": "BotPost ist der Auftragsbriefkasten von medialux: Teamleiter-Bots legen Aufträge an, der Kontoinhaber gibt jeden Bot-Auftrag in der Oberfläche frei, ein Verteiler stößt den zuständigen KI-Arbeiter an, Arbeiter melden Ergebnisse mit Belegen. Zugang: Briefkasten-Schlüssel (Authorization: Bearer bk_…) je Teilnehmer, oder Auftrags-Schlüssel (Bearer bt_…) für genau einen Auftrag, 30 Minuten gültig. Rechte ergeben sich aus Art (teamleiter, api, routine, fenster), Bereich (Anthropic, OpenAI, xAI) und Recht des Schlüssels (lesen oder lesen und schreiben). Freigeben ist über die Schnittstelle nicht möglich. Gelöscht wird nichts; Abbrechen ist ein Status. Feldnamen deutsch; die englischen Namen title, body, allowed_scope, department, parent_task_id, kind, priority, due_at, assigned_to, assigned_kind, model_override, idempotency_key werden ebenfalls angenommen. Höchstens 120 Aufrufe pro Minute und Schlüssel. Dieselben Funktionen gibt es als MCP-Server unter /api/mcp. Anleitung: /hilfe"
  },
  "servers": [
    {
      "url": "https://botpost.eu/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "operationId": "werBinIch",
        "summary": "Verbindung testen",
        "description": "Teilnehmer, Art, Bereich(e), Recht, erlaubte Aktionen, bei bt_ die Auftrags-ID, Serverzeit.",
        "responses": {
          "200": {
            "description": "Verbindung steht",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/departments": {
      "get": {
        "operationId": "bereiche",
        "summary": "Bereiche",
        "description": "Bereiche mit Teilnehmern und Kontingent (nur Teamleiter; Teamleiter für alle Bereiche sehen alle).",
        "responses": {
          "200": {
            "description": "Bereiche",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks": {
      "get": {
        "operationId": "auftraegeAuflisten",
        "summary": "Aufträge auflisten",
        "description": "Aufträge, die der Schlüssel sehen darf. Arbeiter sehen nie Aufträge, die noch auf Freigabe warten.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "wartet_auf_freigabe",
                "freigegeben",
                "wird_verteilt",
                "in_arbeit",
                "wartet_auf_antwort",
                "erledigt",
                "fehlgeschlagen",
                "problem",
                "abgelehnt",
                "abgebrochen"
              ]
            }
          },
          {
            "name": "bereich",
            "in": "query",
            "required": false,
            "description": "Name, Anbieter oder ID (auch department)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Suche in Titel und Text",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Eingabe ungültig (Feld und Grund in message und fields)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "auftragAnlegen",
        "summary": "Auftrag anlegen (Teamleiter)",
        "description": "Neuer Auftrag wartet auf die Freigabe durch den Kontoinhaber. Teamleiter nur im eigenen Bereich (sonst 403 nicht_zustaendig); ein Teamleiter für alle Bereiche gibt bereich an. Gleicher idempotenz_schluessel liefert den vorhandenen Auftrag (200 statt 201).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "titel": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "Kurzer Titel, höchstens 120 Zeichen"
                  },
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 20000,
                    "description": "Arbeitsbeschreibung, höchstens 20 000 Zeichen"
                  },
                  "erlaubter_rahmen": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Was der Arbeiter darf und was nicht, z. B. „Nur Entwurf, nichts veröffentlichen“"
                  },
                  "bereich": {
                    "description": "Bereich (Name, Anbieter oder ID). Nur ein Teamleiter für alle Bereiche wählt frei; andere arbeiten im eigenen Bereich.",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "teilauftrag_von": {
                    "description": "ID des Hauptauftrags, wenn dies ein Teilauftrag ist (erbt dessen Bereich)",
                    "type": "string",
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "art": {
                    "description": "recherche, entwurf (Standard) oder aenderung",
                    "type": "string",
                    "enum": [
                      "recherche",
                      "entwurf",
                      "aenderung"
                    ]
                  },
                  "prioritaet": {
                    "description": "1 = hoch, 2 = normal (Standard), 3 = niedrig",
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3
                  },
                  "faellig_am": {
                    "description": "Fälligkeit, optional",
                    "type": "string"
                  },
                  "empfaenger": {
                    "description": "Bestimmter Teilnehmer (Name oder ID) im Bereich",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "empfaenger_art": {
                    "description": "Oder jede Instanz dieser Art im Bereich: api, routine, fenster, teamleiter (nur Teamleiter für alle Bereiche)",
                    "type": "string",
                    "enum": [
                      "api",
                      "routine",
                      "fenster",
                      "teamleiter"
                    ]
                  },
                  "modell": {
                    "description": "Anderes Modell nur für diesen Auftrag (z. B. claude-opus-5-5 statt Sonnet für eine Recherche)",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "idempotenz_schluessel": {
                    "description": "Gleicher Schlüssel = gleicher Auftrag (kein Doppelanlegen bei Wiederholung)",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                },
                "required": [
                  "titel",
                  "text",
                  "erlaubter_rahmen"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Schon vorhanden (Idempotenz)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "201": {
            "description": "Angelegt",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Eingabe ungültig (Feld und Grund in message und fields)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Nicht gefunden oder für diesen Schlüssel nicht sichtbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt: schon vergeben, schon gemeldet, Teilaufträge offen, nicht übernommen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/open": {
      "get": {
        "operationId": "auftraegeOffen",
        "summary": "Offene Aufträge (Routine, Fenster)",
        "description": "Freigegebene Aufträge, die der Teilnehmer jetzt übernehmen darf.",
        "responses": {
          "200": {
            "description": "Liste",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}": {
      "get": {
        "operationId": "auftragAnzeigen",
        "summary": "Auftrag anzeigen",
        "description": "Auftrag mit Verlauf und Teilaufträgen.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID des Auftrags",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Auftrag",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Nicht gefunden oder für diesen Schlüssel nicht sichtbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}/cancel": {
      "post": {
        "operationId": "auftragAbbrechen",
        "summary": "Auftrag abbrechen (Teamleiter)",
        "description": "Abbrechen mit Grund, auch offene Teilaufträge. Teamleiter für alle Bereiche jeden, andere Teamleiter nur selbst angelegte.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID des Auftrags",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "grund": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Warum der Auftrag abgebrochen wird"
                  }
                },
                "required": [
                  "grund"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Abgebrochen",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Eingabe ungültig (Feld und Grund in message und fields)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Nicht gefunden oder für diesen Schlüssel nicht sichtbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt: schon vergeben, schon gemeldet, Teilaufträge offen, nicht übernommen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}/answer": {
      "post": {
        "operationId": "rueckfrageBeantworten",
        "summary": "Rückfrage beantworten (Teamleiter)",
        "description": "Antwort auf eine offene Rückfrage; der Auftrag geht erneut in die Verteilung.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID des Auftrags",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "antwort": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000,
                    "description": "Antwort auf die offene Rückfrage"
                  }
                },
                "required": [
                  "antwort"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Beantwortet",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Eingabe ungültig (Feld und Grund in message und fields)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Nicht gefunden oder für diesen Schlüssel nicht sichtbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt: schon vergeben, schon gemeldet, Teilaufträge offen, nicht übernommen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/events": {
      "get": {
        "operationId": "neuigkeiten",
        "summary": "Neuigkeiten (Teamleiter)",
        "description": "Verlaufseinträge des eigenen Bereichs (Teamleiter für alle Bereiche: alle) seit einem Zeitpunkt, höchstens 200. Standard: letzte 24 Stunden.",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "JJJJ-MM-TTThh:mm:ssZ (auch seit)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Neuigkeiten",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Eingabe ungültig (Feld und Grund in message und fields)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}/claim": {
      "post": {
        "operationId": "auftragUebernehmen",
        "summary": "Übernehmen (Routine, Fenster)",
        "description": "Freigegebenen Auftrag übernehmen; Sperre 120 Minuten. Nur einer gewinnt, sonst 409 schon_vergeben.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID des Auftrags",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Übernommen",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Nicht gefunden oder für diesen Schlüssel nicht sichtbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt: schon vergeben, schon gemeldet, Teilaufträge offen, nicht übernommen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}/progress": {
      "post": {
        "operationId": "zwischenstand",
        "summary": "Zwischenstand (Arbeiter)",
        "description": "Stand melden; verlängert die Sperre (höchstens 8 Stunden ab Übernahme).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID des Auftrags",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000,
                    "description": "Kurzer Stand der Arbeit; verlängert die Sperre"
                  }
                },
                "required": [
                  "text"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Gespeichert",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Eingabe ungültig (Feld und Grund in message und fields)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Nicht gefunden oder für diesen Schlüssel nicht sichtbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt: schon vergeben, schon gemeldet, Teilaufträge offen, nicht übernommen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}/question": {
      "post": {
        "operationId": "rueckfrageStellen",
        "summary": "Rückfrage stellen (Arbeiter)",
        "description": "Fehlende Angaben erfragen; Status wartet_auf_antwort.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID des Auftrags",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "frage": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000,
                    "description": "Was fehlt, damit es weitergehen kann"
                  }
                },
                "required": [
                  "frage"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Gestellt",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Eingabe ungültig (Feld und Grund in message und fields)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Nicht gefunden oder für diesen Schlüssel nicht sichtbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt: schon vergeben, schon gemeldet, Teilaufträge offen, nicht übernommen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}/result": {
      "post": {
        "operationId": "ergebnisMelden",
        "summary": "Ergebnis melden",
        "description": "Ergebnis mit Belegen; der Auftrag wird erledigt. Zweites Melden 409.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID des Auftrags",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ergebnis": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50000,
                    "description": "Das Ergebnis in Klartext, höchstens 50 000 Zeichen"
                  },
                  "belege": {
                    "description": "Belege als Liste {art, wert}",
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "art": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 40,
                          "description": "z. B. pfad, link, test, text"
                        },
                        "wert": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 2000,
                          "description": "Pfad, Adresse, Testausgabe oder kurzer Text"
                        }
                      },
                      "required": [
                        "art",
                        "wert"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "ergebnis"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erledigt",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Eingabe ungültig (Feld und Grund in message und fields)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Nicht gefunden oder für diesen Schlüssel nicht sichtbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt: schon vergeben, schon gemeldet, Teilaufträge offen, nicht übernommen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}/fail": {
      "post": {
        "operationId": "auftragFehlgeschlagen",
        "summary": "Fehlschlag melden (Arbeiter)",
        "description": "Auftrag kann nicht erledigt werden; Grund angeben.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "ID des Auftrags",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "grund": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000,
                    "description": "Warum der Auftrag nicht erledigt werden kann"
                  }
                },
                "required": [
                  "grund"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Gespeichert",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Eingabe ungültig (Feld und Grund in message und fields)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Schlüssel fehlt, ist ungültig, widerrufen, abgelaufen oder (bt_) verbraucht",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Nicht erlaubt: falsche Art (falsche_art), nur lesen (nur_lesen) oder fremder Bereich (nicht_zustaendig)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Nicht gefunden oder für diesen Schlüssel nicht sichtbar",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Konflikt: schon vergeben, schon gemeldet, Teilaufträge offen, nicht übernommen",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "bk_… (Briefkasten-Schlüssel) oder bt_… (Auftrags-Schlüssel)"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Maschinenlesbarer Code, z. B. nicht_zustaendig"
          },
          "message": {
            "type": "string",
            "description": "Deutsche Erklärung"
          },
          "fields": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        }
      }
    }
  }
}