{
  "openapi": "3.1.0",
  "info": {
    "title": "dealsky API",
    "version": "1.0.0",
    "description": "REST-API für dealsky: Leads, Listen, Kampagnen, LinkedIn, CRM und mehr.\n\n**Anmeldung:** API-Key im Header `X-API-Key` (oder `Authorization: Bearer <key>`). Keys entstehen in der App unter Einstellungen → Integrationen → API Keys. Live-Keys beginnen mit `kv_live_`, Test-Keys mit `kv_test_`. Den Key nie in der URL übergeben und nie im Browser einsetzen.\n\n**Test-Modus:** Mit einem Test-Key liefern lesende Aufrufe echte Daten. Schreibende, löschende und nach außen wirkende Aufrufe werden vollständig geprüft, aber nur simuliert (`meta.test_mode: true`).\n\n**Antwortformat:** Immer `{ ok, data, meta }` bzw. bei Fehlern `{ ok: false, error: { code, message, details } }`. `meta.request_id` bitte bei Support-Anfragen nennen.\n\n**Seitenweise Abruf:** Listen liefern höchstens `limit` Einträge (Standard 25, max. 100). Gibt es mehr, steht in `meta.next_cursor` der Wert für `?cursor=`.\n\n**Limits:** 120 Anfragen pro Minute und 3000 pro Stunde je Key, Body höchstens 1 MB. Bei Überschreitung 429 mit Header `Retry-After`.\n\n**Tarif:** Die API ist ab dem Growth-Tarif mit aktivem Abo enthalten.",
    "contact": {
      "name": "dealsky Support",
      "email": "support@dealsky.io"
    }
  },
  "servers": [
    {
      "url": "https://api.dealsky.io/functions/v1/api",
      "description": "Produktion"
    }
  ],
  "security": [
    {
      "ApiKeyHeader": []
    },
    {
      "BearerKey": []
    }
  ],
  "tags": [
    {
      "name": "Konto",
      "description": "Verbindung prüfen, Tarif, Credits, eigener Key, Doku"
    },
    {
      "name": "Team",
      "description": "Team-Mitglieder und ihre Rollen"
    },
    {
      "name": "Leads",
      "description": "Kontakte anlegen, suchen, pflegen und ihren Verlauf lesen"
    },
    {
      "name": "Listen",
      "description": "Lead-Listen und Ordner verwalten"
    },
    {
      "name": "Ausschlüsse",
      "description": "Blacklist: Wer hier steht, wird nie kontaktiert"
    },
    {
      "name": "Lead Scout",
      "description": "Bisherige Google-Suchen nach neuen Leads lesen"
    },
    {
      "name": "Kampagnen",
      "description": "LinkedIn-Kampagnen, ihre Sequenzen und Kennzahlen lesen"
    },
    {
      "name": "Dauerläufe",
      "description": "LinkedIn-Dauerläufe (Signale): Einstellungen, gefundene Personen und Kontingent lesen"
    },
    {
      "name": "LinkedIn",
      "description": "Verbundene LinkedIn-Konten, ihre Nutzung und Grenzen"
    },
    {
      "name": "Postfach",
      "description": "LinkedIn-Unterhaltungen lesen und pflegen"
    },
    {
      "name": "Vorlagen",
      "description": "Nachrichten- und Sequenz-Vorlagen und die Platzhalter, die Texte in Kampagnen und im Postfach erlauben"
    },
    {
      "name": "CRM",
      "description": "Notizen, Termine, Wiedervorlagen, Kontaktpersonen, Telefonate, Gesprächsleitfäden und Rufnummern"
    },
    {
      "name": "Landingpages",
      "description": "Vorlagen, persönliche Landingpages je Lead und ihre Links"
    },
    {
      "name": "Videos",
      "description": "Personalisierte Videos je Lead"
    },
    {
      "name": "Medien",
      "description": "Bilder, Videos und Audio hochladen und verwalten"
    },
    {
      "name": "Jobs",
      "description": "Stand von Hintergrund-Aufträgen (Erzeugen, Löschen, Umwandeln)"
    },
    {
      "name": "Auswertung",
      "description": "Kennzahlen und Aktivitäten"
    },
    {
      "name": "Webhooks",
      "description": "Ereignisse per Webhook empfangen"
    },
    {
      "name": "Einstellungen",
      "description": "Firmenprofil, eigene Domains und Buchungslinks"
    }
  ],
  "paths": {
    "/v1/me": {
      "get": {
        "operationId": "getMe",
        "tags": [
          "Konto"
        ],
        "summary": "Eigenen API-Key prüfen",
        "description": "Zeigt, zu welchem Konto der Key gehört, welche Berechtigungen er hat und ob er im Test-Modus läuft. Ideal als Verbindungstest.\n\n**Berechtigung:** jeder gültige API-Key\n\n**Wirkung:** Liest nur.",
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "tenant_id": {
                          "type": "string",
                          "description": "ID des Kontos (Mandanten), zu dem der Key gehört",
                          "format": "uuid"
                        },
                        "tenant_name": {
                          "type": "string",
                          "description": "Name des Kontos, leer, wenn keiner hinterlegt ist"
                        },
                        "key_name": {
                          "type": "string",
                          "description": "Name, den der Key beim Anlegen bekommen hat"
                        },
                        "mode": {
                          "type": "string",
                          "description": "test: schreibende Aufrufe werden nur simuliert",
                          "enum": [
                            "live",
                            "test"
                          ]
                        },
                        "scopes": {
                          "type": "array",
                          "description": "Berechtigungen (Scopes) dieses Keys",
                          "items": {
                            "type": "string",
                            "enum": [
                              "read:leads",
                              "write:leads",
                              "delete:leads",
                              "read:exclusions",
                              "write:exclusions",
                              "read:campaigns",
                              "write:campaigns",
                              "run:campaigns",
                              "read:crm",
                              "write:crm",
                              "delete:crm",
                              "read:inbox",
                              "write:inbox",
                              "send:messages",
                              "read:linkedin",
                              "read:analytics",
                              "read:assets",
                              "write:assets",
                              "generate:assets",
                              "read:webhooks",
                              "write:webhooks",
                              "read:team",
                              "read:account"
                            ]
                          }
                        },
                        "plan": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Tarif des Kontos, null, wenn keiner gesetzt ist"
                        },
                        "api_version": {
                          "type": "string",
                          "description": "Version dieser API"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "tenant_id": "3c9d2e1f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                        "tenant_name": "Beispiel GmbH",
                        "key_name": "Zapier",
                        "mode": "live",
                        "scopes": [
                          "read:leads",
                          "write:leads",
                          "read:exclusions",
                          "write:exclusions"
                        ],
                        "plan": "scale",
                        "api_version": "1.0.0"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "key",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "tags": [
          "Konto"
        ],
        "summary": "OpenAPI-Beschreibung dieser API",
        "description": "Maschinenlesbare Beschreibung aller Endpunkte (OpenAPI 3.1). Ohne API-Key abrufbar.\n\n**Ohne API-Key**\n\n**Wirkung:** Liest nur.",
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "openapi": "3.1.0",
                        "info": {
                          "title": "dealsky API",
                          "version": "1.0.0"
                        }
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          }
        },
        "security": [],
        "x-dealsky-scope": null,
        "x-dealsky-risk": "read"
      }
    },
    "/v1/leads": {
      "get": {
        "operationId": "listLeads",
        "tags": [
          "Leads"
        ],
        "summary": "Leads auflisten und filtern",
        "description": "Neueste zuerst. Mehrere Filter werden mit UND verknüpft. `q` sucht in Vorname, Nachname, E-Mail und Firma.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Freitextsuche (Name, E-Mail, Firma)",
              "maxLength": 200
            },
            "description": "Freitextsuche (Name, E-Mail, Firma)"
          },
          {
            "name": "email",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Exakte E-Mail (Groß/Klein egal)",
              "format": "email",
              "maxLength": 320
            },
            "description": "Exakte E-Mail (Groß/Klein egal)"
          },
          {
            "name": "linkedin_url",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "LinkedIn-Profil-URL: findet dieselbe Person in jeder Schreibweise (mit oder ohne www, Länder-Subdomain, Groß/Klein, Parameter, Unterseiten, %-Kodierung) und über die Member-ID, wie die Dublettenprüfung. Andere URLs (z. B. /pub/) exakt.",
              "maxLength": 500
            },
            "description": "LinkedIn-Profil-URL: findet dieselbe Person in jeder Schreibweise (mit oder ohne www, Länder-Subdomain, Groß/Klein, Parameter, Unterseiten, %-Kodierung) und über die Member-ID, wie die Dublettenprüfung. Andere URLs (z. B. /pub/) exakt."
          },
          {
            "name": "list_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Leads dieser Liste (GET /v1/lists)",
              "format": "uuid"
            },
            "description": "Nur Leads dieser Liste (GET /v1/lists)"
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Leads, die dieser Kampagne zugeordnet sind (Feld campaign_id)",
              "format": "uuid"
            },
            "description": "Nur Leads, die dieser Kampagne zugeordnet sind (Feld campaign_id)"
          },
          {
            "name": "company_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Leads, die mit dieser CRM-Firma verknüpft sind",
              "format": "uuid"
            },
            "description": "Nur Leads, die mit dieser CRM-Firma verknüpft sind"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Ein oder mehrere Status, kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "open",
                  "contacted",
                  "not_reached",
                  "interested",
                  "qualified",
                  "follow_up",
                  "booked",
                  "won",
                  "lost",
                  "disqualified",
                  "opt_out",
                  "archived"
                ]
              }
            },
            "description": "Ein oder mehrere Status, kommagetrennt",
            "style": "form",
            "explode": false
          },
          {
            "name": "assigned_user_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Leads dieses Team-Mitglieds (GET /v1/team)",
              "format": "uuid"
            },
            "description": "Nur Leads dieses Team-Mitglieds (GET /v1/team)"
          },
          {
            "name": "show_in_crm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "true: nur Leads im CRM, false: nur Leads außerhalb"
            },
            "description": "true: nur Leads im CRM, false: nur Leads außerhalb"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Leads, die ab diesem Zeitpunkt angelegt wurden",
              "format": "date-time"
            },
            "description": "Nur Leads, die ab diesem Zeitpunkt angelegt wurden"
          },
          {
            "name": "updated_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Leads, die seitdem geändert wurden (für Abgleiche)",
              "format": "date-time"
            },
            "description": "Nur Leads, die seitdem geändert wurden (für Abgleiche)"
          },
          {
            "name": "include_archived",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Archivierte Leads mitliefern (Standard: nein)"
            },
            "description": "Archivierte Leads mitliefern (Standard: nein)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                            "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                            "campaign_id": null,
                            "company_id": null,
                            "salutation": "Herr",
                            "academic_title": "Dr.",
                            "first_name": "Max",
                            "last_name": "Mustermann",
                            "title": "Geschäftsführer",
                            "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                            "email": "max.mustermann@beispiel.de",
                            "email_status": null,
                            "phone": "+49 3012 3456",
                            "company": "Beispiel GmbH",
                            "website": "https://beispiel.de",
                            "employees": "11-50",
                            "street": "Musterstraße 1",
                            "postal_code": "10115",
                            "city": "Berlin",
                            "country": "DE",
                            "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                            "linkedin_network_distance": "DISTANCE_2",
                            "status": "open",
                            "stage": "cold",
                            "outreach_status": "Ausstehend",
                            "score": 15,
                            "lead_source": "api",
                            "source_details": "Messe Köln 2026",
                            "notes": null,
                            "assigned_user_id": null,
                            "show_in_crm": false,
                            "crm_only": false,
                            "is_priority": false,
                            "do_not_contact": false,
                            "meeting_scheduled_at": null,
                            "meeting_type": null,
                            "next_action": null,
                            "next_action_at": null,
                            "landing_page_url": null,
                            "personalized_video_url": null,
                            "personalized_video_thumbnail": null,
                            "landingpage_url_qrcode": null,
                            "utm_source": null,
                            "utm_medium": null,
                            "utm_campaign": null,
                            "utm_content": null,
                            "utm_term": null,
                            "last_activity_at": "2026-10-18T09:12:00.000Z",
                            "archived_at": null,
                            "created_at": "2026-10-01T08:00:00.000Z",
                            "updated_at": "2026-10-18T09:12:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Leads",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "list_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Liste, in der der Lead steht",
                            "format": "uuid"
                          },
                          "campaign_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kampagne, der der Lead zugeordnet ist (Zuordnung über /v1/campaigns/{id}/leads)",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "company_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Verknüpfte CRM-Firma",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "salutation": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Anrede: Herr, Frau, Divers oder Unbekannt",
                            "enum": [
                              "Herr",
                              "Frau",
                              "Divers",
                              "Unbekannt",
                              null
                            ]
                          },
                          "academic_title": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Akademischer Titel, z. B. Dr.",
                            "maxLength": 50
                          },
                          "first_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vorname, in Texten der Platzhalter {{first_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit last_name Pflicht",
                            "maxLength": 200
                          },
                          "last_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nachname, in Texten der Platzhalter {{last_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit first_name Pflicht",
                            "maxLength": 200
                          },
                          "title": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Position im Unternehmen",
                            "maxLength": 300
                          },
                          "headline": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LinkedIn-Headline",
                            "maxLength": 500
                          },
                          "email": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "E-Mail-Adresse, wird klein geschrieben gespeichert. Nutzt ein anderer Lead im Konto dieselbe Adresse (Groß/Klein egal), ist es eine Dublette: einzeln 409, in der Sammel-Anlage status duplicate",
                            "format": "email",
                            "maxLength": 320
                          },
                          "email_status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Ergebnis der E-Mail-Prüfung",
                            "readOnly": true
                          },
                          "phone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Wird wie in der App ins internationale Format gebracht, z. B. +49 3012 3456",
                            "maxLength": 50
                          },
                          "company": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Firmenname, in Texten der Platzhalter {{company}}",
                            "maxLength": 300
                          },
                          "website": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Website der Firma, z. B. https://beispiel.de. Videos mit scrollender Website (POST /v1/leads/{id}/video) zeigen diese Seite",
                            "maxLength": 500
                          },
                          "employees": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Unternehmensgröße, z. B. 11-50",
                            "maxLength": 50
                          },
                          "street": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Straße und Hausnummer",
                            "maxLength": 300
                          },
                          "postal_code": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Postleitzahl",
                            "maxLength": 20
                          },
                          "city": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Ort, in Texten der Platzhalter {{city}}",
                            "maxLength": 200
                          },
                          "country": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Land, wird zu ISO-Code normalisiert (DE, AT, CH …)",
                            "maxLength": 100
                          },
                          "linkedin_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LinkedIn-Profil-URL",
                            "format": "uri",
                            "maxLength": 2048
                          },
                          "linkedin_network_distance": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kontaktgrad zum verbundenen LinkedIn-Konto",
                            "readOnly": true
                          },
                          "status": {
                            "type": "string",
                            "description": "Vertriebsstatus",
                            "enum": [
                              "open",
                              "contacted",
                              "not_reached",
                              "interested",
                              "qualified",
                              "follow_up",
                              "booked",
                              "won",
                              "lost",
                              "disqualified",
                              "opt_out",
                              "archived"
                            ]
                          },
                          "stage": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Temperatur aus dem Scoring: cold, warm, hot",
                            "readOnly": true
                          },
                          "outreach_status": {
                            "type": "string",
                            "description": "Outreach-Status: Ausstehend (Standard), Brief (ein Brief ist in Produktion), Abgemeldet (bei Status opt_out), daneben Email, Linkedin, Beendet, Warten. LinkedIn-Kampagnen ändern ihn nicht, ihren Stand je Lead liefert GET /v1/campaigns/{id}/leads",
                            "readOnly": true,
                            "enum": [
                              "Ausstehend",
                              "Brief",
                              "Email",
                              "Linkedin",
                              "Beendet",
                              "Warten",
                              "Abgemeldet"
                            ]
                          },
                          "score": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Lead-Score 0 bis 100",
                            "readOnly": true
                          },
                          "lead_source": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Herkunft. System: lead_scout, lead_finder, csv_import, api, manual, webhook; eigene Werte aus den Einstellungen",
                            "maxLength": 100
                          },
                          "source_details": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Freitext zur Herkunft, z. B. Messe Köln 2026",
                            "maxLength": 1000
                          },
                          "notes": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Freitext-Notiz am Lead",
                            "maxLength": 10000
                          },
                          "assigned_user_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zuständiges Team-Mitglied (siehe /v1/team)",
                            "format": "uuid"
                          },
                          "show_in_crm": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Im CRM anzeigen"
                          },
                          "crm_only": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Markierung aus dem CRM-Modul, Standard false. Über die API nicht änderbar",
                            "readOnly": true
                          },
                          "is_priority": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Als Priorität markiert. Die App sortiert solche Leads bei Wiedervorlagen und unter „Nächster Lead“ nach vorn"
                          },
                          "do_not_contact": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Gesperrt für jede Ansprache",
                            "readOnly": true
                          },
                          "meeting_scheduled_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt des vereinbarten Termins. Eintragen wie in der App (Art, optional Status booked) über PUT /v1/leads/{id}/meeting",
                            "format": "date-time"
                          },
                          "meeting_type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Art des Termins: setting, closing, demo oder other",
                            "enum": [
                              "setting",
                              "closing",
                              "demo",
                              "other",
                              null
                            ]
                          },
                          "next_action": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nächster Schritt: call, email, meeting, proposal oder wait (Zeitpunkt in next_action_at)",
                            "enum": [
                              "call",
                              "email",
                              "meeting",
                              "proposal",
                              "wait",
                              null
                            ]
                          },
                          "next_action_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt für den nächsten Schritt aus next_action",
                            "format": "date-time"
                          },
                          "landing_page_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL der personalisierten Landingpage des Leads, null solange keine erzeugt wurde",
                            "readOnly": true
                          },
                          "personalized_video_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL des personalisierten Videos, null solange keins erzeugt wurde (POST /v1/leads/{id}/video)",
                            "readOnly": true
                          },
                          "personalized_video_thumbnail": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL des Vorschaubilds zum personalisierten Video, null ohne Video",
                            "readOnly": true
                          },
                          "landingpage_url_qrcode": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL eines QR-Code-Bilds, das auf landing_page_url zeigt (z. B. für Briefe), null solange keiner erzeugt wurde",
                            "readOnly": true
                          },
                          "utm_source": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_source der Herkunft (Quelle, z. B. newsletter)",
                            "maxLength": 200
                          },
                          "utm_medium": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_medium der Herkunft (Medium, z. B. email)",
                            "maxLength": 200
                          },
                          "utm_campaign": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_campaign der Herkunft (Name der Werbekampagne)",
                            "maxLength": 200
                          },
                          "utm_content": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_content der Herkunft (Anzeige oder Link)",
                            "maxLength": 200
                          },
                          "utm_term": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_term der Herkunft (Suchbegriff)",
                            "maxLength": 200
                          },
                          "last_activity_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der letzten Aktivität am Lead (ISO 8601, UTC), null ohne Aktivität",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "archived_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der Archivierung (ISO 8601, UTC), null bei aktiven Leads. GET /v1/leads zeigt archivierte nur mit include_archived",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Anlagezeitpunkt (ISO 8601, UTC)",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der letzten Änderung (ISO 8601, UTC)",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Offene Leads einer Liste",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "campaign_id": null,
                          "company_id": null,
                          "salutation": "Herr",
                          "academic_title": "Dr.",
                          "first_name": "Max",
                          "last_name": "Mustermann",
                          "title": "Geschäftsführer",
                          "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                          "email": "max.mustermann@beispiel.de",
                          "email_status": null,
                          "phone": "+49 3012 3456",
                          "company": "Beispiel GmbH",
                          "website": "https://beispiel.de",
                          "employees": "11-50",
                          "street": "Musterstraße 1",
                          "postal_code": "10115",
                          "city": "Berlin",
                          "country": "DE",
                          "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                          "linkedin_network_distance": "DISTANCE_2",
                          "status": "open",
                          "stage": "cold",
                          "outreach_status": "Ausstehend",
                          "score": 15,
                          "lead_source": "api",
                          "source_details": "Messe Köln 2026",
                          "notes": null,
                          "assigned_user_id": null,
                          "show_in_crm": false,
                          "crm_only": false,
                          "is_priority": false,
                          "do_not_contact": false,
                          "meeting_scheduled_at": null,
                          "meeting_type": null,
                          "next_action": null,
                          "next_action_at": null,
                          "landing_page_url": null,
                          "personalized_video_url": null,
                          "personalized_video_thumbnail": null,
                          "landingpage_url_qrcode": null,
                          "utm_source": null,
                          "utm_medium": null,
                          "utm_campaign": null,
                          "utm_content": null,
                          "utm_term": null,
                          "last_activity_at": "2026-10-18T09:12:00.000Z",
                          "archived_at": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Lead zu einem LinkedIn-Profil, egal in welcher Schreibweise",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "campaign_id": null,
                          "company_id": null,
                          "salutation": "Herr",
                          "academic_title": "Dr.",
                          "first_name": "Max",
                          "last_name": "Mustermann",
                          "title": "Geschäftsführer",
                          "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                          "email": "max.mustermann@beispiel.de",
                          "email_status": null,
                          "phone": "+49 3012 3456",
                          "company": "Beispiel GmbH",
                          "website": "https://beispiel.de",
                          "employees": "11-50",
                          "street": "Musterstraße 1",
                          "postal_code": "10115",
                          "city": "Berlin",
                          "country": "DE",
                          "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                          "linkedin_network_distance": "DISTANCE_2",
                          "status": "open",
                          "stage": "cold",
                          "outreach_status": "Ausstehend",
                          "score": 15,
                          "lead_source": "api",
                          "source_details": "Messe Köln 2026",
                          "notes": null,
                          "assigned_user_id": null,
                          "show_in_crm": false,
                          "crm_only": false,
                          "is_priority": false,
                          "do_not_contact": false,
                          "meeting_scheduled_at": null,
                          "meeting_type": null,
                          "next_action": null,
                          "next_action_at": null,
                          "landing_page_url": null,
                          "personalized_video_url": null,
                          "personalized_video_thumbnail": null,
                          "landingpage_url_qrcode": null,
                          "utm_source": null,
                          "utm_medium": null,
                          "utm_campaign": null,
                          "utm_content": null,
                          "utm_term": null,
                          "last_activity_at": "2026-10-18T09:12:00.000Z",
                          "archived_at": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      },
      "post": {
        "operationId": "createLead",
        "tags": [
          "Leads"
        ],
        "summary": "Lead anlegen",
        "description": "Legt einen Lead in einer Liste an. Dubletten (gleiche E-Mail oder dieselbe LinkedIn-Person im Konto) werden mit 409 abgelehnt; `error.details.existing_id` nennt den ältesten vorhandenen Lead, der sich dann per PATCH ändern lässt. Telefonnummern bekommen die Ländervorwahl (+49 …), Länder werden zu ISO-Codes.\n\n**Dieselbe LinkedIn-Person** erkennt die API wie die App beim CSV-Import: am Profil-Slug aus `linkedin.com/in/<slug>`, egal ob mit oder ohne www, mit Länder-Subdomain (de.linkedin.com), in Groß- oder Kleinschreibung, mit Parametern (?trk=…, ?miniProfileUrn=…), Unterseiten (/details/…), Schrägstrich am Ende oder %-kodierten Umlauten. Steht im Slug die LinkedIn-ID (/in/ACoAA… oder /in/ACwAA… aus Sales-Navigator-Exporten), trifft sie auch einen Lead, der diese ID als Member-ID führt. Andere URLs (z. B. /pub/…) werden exakt verglichen. Gespeichert wird die URL so, wie sie übergeben wurde.\n\n**Berechtigung:** `write:leads`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Mindestens eines von email, linkedin_url oder Vor- und Nachname ist nötig.",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "ID des Leads",
                    "readOnly": true,
                    "format": "uuid"
                  },
                  "list_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Liste, in der der Lead steht",
                    "format": "uuid"
                  },
                  "campaign_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Kampagne, der der Lead zugeordnet ist (Zuordnung über /v1/campaigns/{id}/leads)",
                    "readOnly": true,
                    "format": "uuid"
                  },
                  "company_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Verknüpfte CRM-Firma",
                    "readOnly": true,
                    "format": "uuid"
                  },
                  "salutation": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Anrede: Herr, Frau, Divers oder Unbekannt",
                    "enum": [
                      "Herr",
                      "Frau",
                      "Divers",
                      "Unbekannt",
                      null
                    ]
                  },
                  "academic_title": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Akademischer Titel, z. B. Dr.",
                    "maxLength": 50
                  },
                  "first_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Vorname, in Texten der Platzhalter {{first_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit last_name Pflicht",
                    "maxLength": 200
                  },
                  "last_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Nachname, in Texten der Platzhalter {{last_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit first_name Pflicht",
                    "maxLength": 200
                  },
                  "title": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Position im Unternehmen",
                    "maxLength": 300
                  },
                  "headline": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "LinkedIn-Headline",
                    "maxLength": 500
                  },
                  "email": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "E-Mail-Adresse, wird klein geschrieben gespeichert. Nutzt ein anderer Lead im Konto dieselbe Adresse (Groß/Klein egal), ist es eine Dublette: einzeln 409, in der Sammel-Anlage status duplicate",
                    "format": "email",
                    "maxLength": 320
                  },
                  "email_status": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Ergebnis der E-Mail-Prüfung",
                    "readOnly": true
                  },
                  "phone": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Wird wie in der App ins internationale Format gebracht, z. B. +49 3012 3456",
                    "maxLength": 50
                  },
                  "company": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Firmenname, in Texten der Platzhalter {{company}}",
                    "maxLength": 300
                  },
                  "website": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Website der Firma, z. B. https://beispiel.de. Videos mit scrollender Website (POST /v1/leads/{id}/video) zeigen diese Seite",
                    "maxLength": 500
                  },
                  "employees": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Unternehmensgröße, z. B. 11-50",
                    "maxLength": 50
                  },
                  "street": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Straße und Hausnummer",
                    "maxLength": 300
                  },
                  "postal_code": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Postleitzahl",
                    "maxLength": 20
                  },
                  "city": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Ort, in Texten der Platzhalter {{city}}",
                    "maxLength": 200
                  },
                  "country": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Land, wird zu ISO-Code normalisiert (DE, AT, CH …)",
                    "maxLength": 100
                  },
                  "linkedin_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "LinkedIn-Profil-URL",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "linkedin_network_distance": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Kontaktgrad zum verbundenen LinkedIn-Konto",
                    "readOnly": true
                  },
                  "status": {
                    "type": "string",
                    "description": "Standard: open",
                    "enum": [
                      "open",
                      "contacted",
                      "not_reached",
                      "interested",
                      "qualified",
                      "follow_up",
                      "booked",
                      "won",
                      "lost",
                      "disqualified",
                      "opt_out",
                      "archived"
                    ]
                  },
                  "stage": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Temperatur aus dem Scoring: cold, warm, hot",
                    "readOnly": true
                  },
                  "outreach_status": {
                    "type": "string",
                    "description": "Outreach-Status: Ausstehend (Standard), Brief (ein Brief ist in Produktion), Abgemeldet (bei Status opt_out), daneben Email, Linkedin, Beendet, Warten. LinkedIn-Kampagnen ändern ihn nicht, ihren Stand je Lead liefert GET /v1/campaigns/{id}/leads",
                    "readOnly": true,
                    "enum": [
                      "Ausstehend",
                      "Brief",
                      "Email",
                      "Linkedin",
                      "Beendet",
                      "Warten",
                      "Abgemeldet"
                    ]
                  },
                  "score": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "Lead-Score 0 bis 100",
                    "readOnly": true
                  },
                  "lead_source": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Herkunft. System: lead_scout, lead_finder, csv_import, api, manual, webhook; eigene Werte aus den Einstellungen",
                    "maxLength": 100
                  },
                  "source_details": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Freitext zur Herkunft, z. B. Messe Köln 2026",
                    "maxLength": 1000
                  },
                  "notes": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Freitext-Notiz am Lead",
                    "maxLength": 10000
                  },
                  "assigned_user_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zuständiges Team-Mitglied (siehe /v1/team)",
                    "format": "uuid"
                  },
                  "show_in_crm": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Im CRM anzeigen"
                  },
                  "crm_only": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Markierung aus dem CRM-Modul, Standard false. Über die API nicht änderbar",
                    "readOnly": true
                  },
                  "is_priority": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Als Priorität markiert. Die App sortiert solche Leads bei Wiedervorlagen und unter „Nächster Lead“ nach vorn"
                  },
                  "do_not_contact": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Gesperrt für jede Ansprache",
                    "readOnly": true
                  },
                  "meeting_scheduled_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt des vereinbarten Termins. Eintragen wie in der App (Art, optional Status booked) über PUT /v1/leads/{id}/meeting",
                    "format": "date-time"
                  },
                  "meeting_type": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Art des Termins: setting, closing, demo oder other",
                    "enum": [
                      "setting",
                      "closing",
                      "demo",
                      "other",
                      null
                    ]
                  },
                  "next_action": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Nächster Schritt: call, email, meeting, proposal oder wait (Zeitpunkt in next_action_at)",
                    "enum": [
                      "call",
                      "email",
                      "meeting",
                      "proposal",
                      "wait",
                      null
                    ]
                  },
                  "next_action_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt für den nächsten Schritt aus next_action",
                    "format": "date-time"
                  },
                  "landing_page_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "URL der personalisierten Landingpage des Leads, null solange keine erzeugt wurde",
                    "readOnly": true
                  },
                  "personalized_video_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "URL des personalisierten Videos, null solange keins erzeugt wurde (POST /v1/leads/{id}/video)",
                    "readOnly": true
                  },
                  "personalized_video_thumbnail": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "URL des Vorschaubilds zum personalisierten Video, null ohne Video",
                    "readOnly": true
                  },
                  "landingpage_url_qrcode": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "URL eines QR-Code-Bilds, das auf landing_page_url zeigt (z. B. für Briefe), null solange keiner erzeugt wurde",
                    "readOnly": true
                  },
                  "utm_source": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_source der Herkunft (Quelle, z. B. newsletter)",
                    "maxLength": 200
                  },
                  "utm_medium": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_medium der Herkunft (Medium, z. B. email)",
                    "maxLength": 200
                  },
                  "utm_campaign": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_campaign der Herkunft (Name der Werbekampagne)",
                    "maxLength": 200
                  },
                  "utm_content": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_content der Herkunft (Anzeige oder Link)",
                    "maxLength": 200
                  },
                  "utm_term": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_term der Herkunft (Suchbegriff)",
                    "maxLength": 200
                  },
                  "last_activity_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt der letzten Aktivität am Lead (ISO 8601, UTC), null ohne Aktivität",
                    "readOnly": true,
                    "format": "date-time"
                  },
                  "archived_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt der Archivierung (ISO 8601, UTC), null bei aktiven Leads. GET /v1/leads zeigt archivierte nur mit include_archived",
                    "readOnly": true,
                    "format": "date-time"
                  },
                  "created_at": {
                    "type": "string",
                    "description": "Anlagezeitpunkt (ISO 8601, UTC)",
                    "readOnly": true,
                    "format": "date-time"
                  },
                  "updated_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt der letzten Änderung (ISO 8601, UTC)",
                    "readOnly": true,
                    "format": "date-time"
                  }
                },
                "required": [
                  "list_id"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                    "first_name": "Max",
                    "last_name": "Mustermann",
                    "email": "max.mustermann@beispiel.de",
                    "company": "Beispiel GmbH",
                    "phone": "030 123456",
                    "country": "Deutschland",
                    "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                    "lead_source": "api"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "campaign_id": null,
                          "company_id": null,
                          "salutation": "Herr",
                          "academic_title": "Dr.",
                          "first_name": "Max",
                          "last_name": "Mustermann",
                          "title": "Geschäftsführer",
                          "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                          "email": "max.mustermann@beispiel.de",
                          "email_status": null,
                          "phone": "+49 3012 3456",
                          "company": "Beispiel GmbH",
                          "website": "https://beispiel.de",
                          "employees": "11-50",
                          "street": "Musterstraße 1",
                          "postal_code": "10115",
                          "city": "Berlin",
                          "country": "DE",
                          "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                          "linkedin_network_distance": "DISTANCE_2",
                          "status": "open",
                          "stage": "cold",
                          "outreach_status": "Ausstehend",
                          "score": 15,
                          "lead_source": "api",
                          "source_details": "Messe Köln 2026",
                          "notes": null,
                          "assigned_user_id": null,
                          "show_in_crm": false,
                          "crm_only": false,
                          "is_priority": false,
                          "do_not_contact": false,
                          "meeting_scheduled_at": null,
                          "meeting_type": null,
                          "next_action": null,
                          "next_action_at": null,
                          "landing_page_url": null,
                          "personalized_video_url": null,
                          "personalized_video_thumbnail": null,
                          "landingpage_url_qrcode": null,
                          "utm_source": null,
                          "utm_medium": null,
                          "utm_campaign": null,
                          "utm_content": null,
                          "utm_term": null,
                          "last_activity_at": "2026-10-18T09:12:00.000Z",
                          "archived_at": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "list_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Liste, in der der Lead steht",
                          "format": "uuid"
                        },
                        "campaign_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kampagne, der der Lead zugeordnet ist (Zuordnung über /v1/campaigns/{id}/leads)",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "company_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Verknüpfte CRM-Firma",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "salutation": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Anrede: Herr, Frau, Divers oder Unbekannt",
                          "enum": [
                            "Herr",
                            "Frau",
                            "Divers",
                            "Unbekannt",
                            null
                          ]
                        },
                        "academic_title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Akademischer Titel, z. B. Dr.",
                          "maxLength": 50
                        },
                        "first_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorname, in Texten der Platzhalter {{first_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit last_name Pflicht",
                          "maxLength": 200
                        },
                        "last_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nachname, in Texten der Platzhalter {{last_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit first_name Pflicht",
                          "maxLength": 200
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Position im Unternehmen",
                          "maxLength": 300
                        },
                        "headline": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Headline",
                          "maxLength": 500
                        },
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "E-Mail-Adresse, wird klein geschrieben gespeichert. Nutzt ein anderer Lead im Konto dieselbe Adresse (Groß/Klein egal), ist es eine Dublette: einzeln 409, in der Sammel-Anlage status duplicate",
                          "format": "email",
                          "maxLength": 320
                        },
                        "email_status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ergebnis der E-Mail-Prüfung",
                          "readOnly": true
                        },
                        "phone": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Wird wie in der App ins internationale Format gebracht, z. B. +49 3012 3456",
                          "maxLength": 50
                        },
                        "company": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Firmenname, in Texten der Platzhalter {{company}}",
                          "maxLength": 300
                        },
                        "website": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Website der Firma, z. B. https://beispiel.de. Videos mit scrollender Website (POST /v1/leads/{id}/video) zeigen diese Seite",
                          "maxLength": 500
                        },
                        "employees": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Unternehmensgröße, z. B. 11-50",
                          "maxLength": 50
                        },
                        "street": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Straße und Hausnummer",
                          "maxLength": 300
                        },
                        "postal_code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Postleitzahl",
                          "maxLength": 20
                        },
                        "city": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ort, in Texten der Platzhalter {{city}}",
                          "maxLength": 200
                        },
                        "country": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Land, wird zu ISO-Code normalisiert (DE, AT, CH …)",
                          "maxLength": 100
                        },
                        "linkedin_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Profil-URL",
                          "format": "uri",
                          "maxLength": 2048
                        },
                        "linkedin_network_distance": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kontaktgrad zum verbundenen LinkedIn-Konto",
                          "readOnly": true
                        },
                        "status": {
                          "type": "string",
                          "description": "Vertriebsstatus",
                          "enum": [
                            "open",
                            "contacted",
                            "not_reached",
                            "interested",
                            "qualified",
                            "follow_up",
                            "booked",
                            "won",
                            "lost",
                            "disqualified",
                            "opt_out",
                            "archived"
                          ]
                        },
                        "stage": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Temperatur aus dem Scoring: cold, warm, hot",
                          "readOnly": true
                        },
                        "outreach_status": {
                          "type": "string",
                          "description": "Outreach-Status: Ausstehend (Standard), Brief (ein Brief ist in Produktion), Abgemeldet (bei Status opt_out), daneben Email, Linkedin, Beendet, Warten. LinkedIn-Kampagnen ändern ihn nicht, ihren Stand je Lead liefert GET /v1/campaigns/{id}/leads",
                          "readOnly": true,
                          "enum": [
                            "Ausstehend",
                            "Brief",
                            "Email",
                            "Linkedin",
                            "Beendet",
                            "Warten",
                            "Abgemeldet"
                          ]
                        },
                        "score": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Lead-Score 0 bis 100",
                          "readOnly": true
                        },
                        "lead_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Herkunft. System: lead_scout, lead_finder, csv_import, api, manual, webhook; eigene Werte aus den Einstellungen",
                          "maxLength": 100
                        },
                        "source_details": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext zur Herkunft, z. B. Messe Köln 2026",
                          "maxLength": 1000
                        },
                        "notes": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext-Notiz am Lead",
                          "maxLength": 10000
                        },
                        "assigned_user_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zuständiges Team-Mitglied (siehe /v1/team)",
                          "format": "uuid"
                        },
                        "show_in_crm": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Im CRM anzeigen"
                        },
                        "crm_only": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Markierung aus dem CRM-Modul, Standard false. Über die API nicht änderbar",
                          "readOnly": true
                        },
                        "is_priority": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Als Priorität markiert. Die App sortiert solche Leads bei Wiedervorlagen und unter „Nächster Lead“ nach vorn"
                        },
                        "do_not_contact": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Gesperrt für jede Ansprache",
                          "readOnly": true
                        },
                        "meeting_scheduled_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt des vereinbarten Termins. Eintragen wie in der App (Art, optional Status booked) über PUT /v1/leads/{id}/meeting",
                          "format": "date-time"
                        },
                        "meeting_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Art des Termins: setting, closing, demo oder other",
                          "enum": [
                            "setting",
                            "closing",
                            "demo",
                            "other",
                            null
                          ]
                        },
                        "next_action": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nächster Schritt: call, email, meeting, proposal oder wait (Zeitpunkt in next_action_at)",
                          "enum": [
                            "call",
                            "email",
                            "meeting",
                            "proposal",
                            "wait",
                            null
                          ]
                        },
                        "next_action_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt für den nächsten Schritt aus next_action",
                          "format": "date-time"
                        },
                        "landing_page_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL der personalisierten Landingpage des Leads, null solange keine erzeugt wurde",
                          "readOnly": true
                        },
                        "personalized_video_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL des personalisierten Videos, null solange keins erzeugt wurde (POST /v1/leads/{id}/video)",
                          "readOnly": true
                        },
                        "personalized_video_thumbnail": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL des Vorschaubilds zum personalisierten Video, null ohne Video",
                          "readOnly": true
                        },
                        "landingpage_url_qrcode": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL eines QR-Code-Bilds, das auf landing_page_url zeigt (z. B. für Briefe), null solange keiner erzeugt wurde",
                          "readOnly": true
                        },
                        "utm_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_source der Herkunft (Quelle, z. B. newsletter)",
                          "maxLength": 200
                        },
                        "utm_medium": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_medium der Herkunft (Medium, z. B. email)",
                          "maxLength": 200
                        },
                        "utm_campaign": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_campaign der Herkunft (Name der Werbekampagne)",
                          "maxLength": 200
                        },
                        "utm_content": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_content der Herkunft (Anzeige oder Link)",
                          "maxLength": 200
                        },
                        "utm_term": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_term der Herkunft (Suchbegriff)",
                          "maxLength": 200
                        },
                        "last_activity_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Aktivität am Lead (ISO 8601, UTC), null ohne Aktivität",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "archived_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der Archivierung (ISO 8601, UTC), null bei aktiven Leads. GET /v1/leads zeigt archivierte nur mit include_archived",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Anlagezeitpunkt (ISO 8601, UTC)",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung (ISO 8601, UTC)",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "campaign_id": null,
                        "company_id": null,
                        "salutation": "Herr",
                        "academic_title": "Dr.",
                        "first_name": "Max",
                        "last_name": "Mustermann",
                        "title": "Geschäftsführer",
                        "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                        "email": "max.mustermann@beispiel.de",
                        "email_status": null,
                        "phone": "+49 3012 3456",
                        "company": "Beispiel GmbH",
                        "website": "https://beispiel.de",
                        "employees": "11-50",
                        "street": "Musterstraße 1",
                        "postal_code": "10115",
                        "city": "Berlin",
                        "country": "DE",
                        "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                        "linkedin_network_distance": "DISTANCE_2",
                        "status": "open",
                        "stage": "cold",
                        "outreach_status": "Ausstehend",
                        "score": 15,
                        "lead_source": "api",
                        "source_details": "Messe Köln 2026",
                        "notes": null,
                        "assigned_user_id": null,
                        "show_in_crm": false,
                        "crm_only": false,
                        "is_priority": false,
                        "do_not_contact": false,
                        "meeting_scheduled_at": null,
                        "meeting_type": null,
                        "next_action": null,
                        "next_action_at": null,
                        "landing_page_url": null,
                        "personalized_video_url": null,
                        "personalized_video_thumbnail": null,
                        "landingpage_url_qrcode": null,
                        "utm_source": null,
                        "utm_medium": null,
                        "utm_campaign": null,
                        "utm_content": null,
                        "utm_term": null,
                        "last_activity_at": "2026-10-18T09:12:00.000Z",
                        "archived_at": null,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:leads",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/leads/{id}": {
      "get": {
        "operationId": "getLead",
        "tags": [
          "Leads"
        ],
        "summary": "Einen Lead abrufen",
        "description": "Liefert einen Lead des eigenen Kontos mit denselben Feldern wie `GET /v1/leads`, auch wenn er archiviert ist (`archived_at` gesetzt). Eine unbekannte oder fremde ID ergibt 404. Werte der eigenen Felder liefert `GET /v1/leads/{id}/custom-fields`, den Verlauf `GET /v1/leads/{id}/activities`.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "campaign_id": null,
                          "company_id": null,
                          "salutation": "Herr",
                          "academic_title": "Dr.",
                          "first_name": "Max",
                          "last_name": "Mustermann",
                          "title": "Geschäftsführer",
                          "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                          "email": "max.mustermann@beispiel.de",
                          "email_status": null,
                          "phone": "+49 3012 3456",
                          "company": "Beispiel GmbH",
                          "website": "https://beispiel.de",
                          "employees": "11-50",
                          "street": "Musterstraße 1",
                          "postal_code": "10115",
                          "city": "Berlin",
                          "country": "DE",
                          "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                          "linkedin_network_distance": "DISTANCE_2",
                          "status": "open",
                          "stage": "cold",
                          "outreach_status": "Ausstehend",
                          "score": 15,
                          "lead_source": "api",
                          "source_details": "Messe Köln 2026",
                          "notes": null,
                          "assigned_user_id": null,
                          "show_in_crm": false,
                          "crm_only": false,
                          "is_priority": false,
                          "do_not_contact": false,
                          "meeting_scheduled_at": null,
                          "meeting_type": null,
                          "next_action": null,
                          "next_action_at": null,
                          "landing_page_url": null,
                          "personalized_video_url": null,
                          "personalized_video_thumbnail": null,
                          "landingpage_url_qrcode": null,
                          "utm_source": null,
                          "utm_medium": null,
                          "utm_campaign": null,
                          "utm_content": null,
                          "utm_term": null,
                          "last_activity_at": "2026-10-18T09:12:00.000Z",
                          "archived_at": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "list_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Liste, in der der Lead steht",
                          "format": "uuid"
                        },
                        "campaign_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kampagne, der der Lead zugeordnet ist (Zuordnung über /v1/campaigns/{id}/leads)",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "company_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Verknüpfte CRM-Firma",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "salutation": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Anrede: Herr, Frau, Divers oder Unbekannt",
                          "enum": [
                            "Herr",
                            "Frau",
                            "Divers",
                            "Unbekannt",
                            null
                          ]
                        },
                        "academic_title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Akademischer Titel, z. B. Dr.",
                          "maxLength": 50
                        },
                        "first_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorname, in Texten der Platzhalter {{first_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit last_name Pflicht",
                          "maxLength": 200
                        },
                        "last_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nachname, in Texten der Platzhalter {{last_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit first_name Pflicht",
                          "maxLength": 200
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Position im Unternehmen",
                          "maxLength": 300
                        },
                        "headline": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Headline",
                          "maxLength": 500
                        },
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "E-Mail-Adresse, wird klein geschrieben gespeichert. Nutzt ein anderer Lead im Konto dieselbe Adresse (Groß/Klein egal), ist es eine Dublette: einzeln 409, in der Sammel-Anlage status duplicate",
                          "format": "email",
                          "maxLength": 320
                        },
                        "email_status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ergebnis der E-Mail-Prüfung",
                          "readOnly": true
                        },
                        "phone": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Wird wie in der App ins internationale Format gebracht, z. B. +49 3012 3456",
                          "maxLength": 50
                        },
                        "company": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Firmenname, in Texten der Platzhalter {{company}}",
                          "maxLength": 300
                        },
                        "website": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Website der Firma, z. B. https://beispiel.de. Videos mit scrollender Website (POST /v1/leads/{id}/video) zeigen diese Seite",
                          "maxLength": 500
                        },
                        "employees": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Unternehmensgröße, z. B. 11-50",
                          "maxLength": 50
                        },
                        "street": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Straße und Hausnummer",
                          "maxLength": 300
                        },
                        "postal_code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Postleitzahl",
                          "maxLength": 20
                        },
                        "city": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ort, in Texten der Platzhalter {{city}}",
                          "maxLength": 200
                        },
                        "country": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Land, wird zu ISO-Code normalisiert (DE, AT, CH …)",
                          "maxLength": 100
                        },
                        "linkedin_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Profil-URL",
                          "format": "uri",
                          "maxLength": 2048
                        },
                        "linkedin_network_distance": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kontaktgrad zum verbundenen LinkedIn-Konto",
                          "readOnly": true
                        },
                        "status": {
                          "type": "string",
                          "description": "Vertriebsstatus",
                          "enum": [
                            "open",
                            "contacted",
                            "not_reached",
                            "interested",
                            "qualified",
                            "follow_up",
                            "booked",
                            "won",
                            "lost",
                            "disqualified",
                            "opt_out",
                            "archived"
                          ]
                        },
                        "stage": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Temperatur aus dem Scoring: cold, warm, hot",
                          "readOnly": true
                        },
                        "outreach_status": {
                          "type": "string",
                          "description": "Outreach-Status: Ausstehend (Standard), Brief (ein Brief ist in Produktion), Abgemeldet (bei Status opt_out), daneben Email, Linkedin, Beendet, Warten. LinkedIn-Kampagnen ändern ihn nicht, ihren Stand je Lead liefert GET /v1/campaigns/{id}/leads",
                          "readOnly": true,
                          "enum": [
                            "Ausstehend",
                            "Brief",
                            "Email",
                            "Linkedin",
                            "Beendet",
                            "Warten",
                            "Abgemeldet"
                          ]
                        },
                        "score": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Lead-Score 0 bis 100",
                          "readOnly": true
                        },
                        "lead_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Herkunft. System: lead_scout, lead_finder, csv_import, api, manual, webhook; eigene Werte aus den Einstellungen",
                          "maxLength": 100
                        },
                        "source_details": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext zur Herkunft, z. B. Messe Köln 2026",
                          "maxLength": 1000
                        },
                        "notes": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext-Notiz am Lead",
                          "maxLength": 10000
                        },
                        "assigned_user_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zuständiges Team-Mitglied (siehe /v1/team)",
                          "format": "uuid"
                        },
                        "show_in_crm": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Im CRM anzeigen"
                        },
                        "crm_only": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Markierung aus dem CRM-Modul, Standard false. Über die API nicht änderbar",
                          "readOnly": true
                        },
                        "is_priority": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Als Priorität markiert. Die App sortiert solche Leads bei Wiedervorlagen und unter „Nächster Lead“ nach vorn"
                        },
                        "do_not_contact": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Gesperrt für jede Ansprache",
                          "readOnly": true
                        },
                        "meeting_scheduled_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt des vereinbarten Termins. Eintragen wie in der App (Art, optional Status booked) über PUT /v1/leads/{id}/meeting",
                          "format": "date-time"
                        },
                        "meeting_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Art des Termins: setting, closing, demo oder other",
                          "enum": [
                            "setting",
                            "closing",
                            "demo",
                            "other",
                            null
                          ]
                        },
                        "next_action": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nächster Schritt: call, email, meeting, proposal oder wait (Zeitpunkt in next_action_at)",
                          "enum": [
                            "call",
                            "email",
                            "meeting",
                            "proposal",
                            "wait",
                            null
                          ]
                        },
                        "next_action_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt für den nächsten Schritt aus next_action",
                          "format": "date-time"
                        },
                        "landing_page_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL der personalisierten Landingpage des Leads, null solange keine erzeugt wurde",
                          "readOnly": true
                        },
                        "personalized_video_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL des personalisierten Videos, null solange keins erzeugt wurde (POST /v1/leads/{id}/video)",
                          "readOnly": true
                        },
                        "personalized_video_thumbnail": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL des Vorschaubilds zum personalisierten Video, null ohne Video",
                          "readOnly": true
                        },
                        "landingpage_url_qrcode": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL eines QR-Code-Bilds, das auf landing_page_url zeigt (z. B. für Briefe), null solange keiner erzeugt wurde",
                          "readOnly": true
                        },
                        "utm_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_source der Herkunft (Quelle, z. B. newsletter)",
                          "maxLength": 200
                        },
                        "utm_medium": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_medium der Herkunft (Medium, z. B. email)",
                          "maxLength": 200
                        },
                        "utm_campaign": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_campaign der Herkunft (Name der Werbekampagne)",
                          "maxLength": 200
                        },
                        "utm_content": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_content der Herkunft (Anzeige oder Link)",
                          "maxLength": 200
                        },
                        "utm_term": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_term der Herkunft (Suchbegriff)",
                          "maxLength": 200
                        },
                        "last_activity_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Aktivität am Lead (ISO 8601, UTC), null ohne Aktivität",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "archived_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der Archivierung (ISO 8601, UTC), null bei aktiven Leads. GET /v1/leads zeigt archivierte nur mit include_archived",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Anlagezeitpunkt (ISO 8601, UTC)",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung (ISO 8601, UTC)",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "campaign_id": null,
                        "company_id": null,
                        "salutation": "Herr",
                        "academic_title": "Dr.",
                        "first_name": "Max",
                        "last_name": "Mustermann",
                        "title": "Geschäftsführer",
                        "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                        "email": "max.mustermann@beispiel.de",
                        "email_status": null,
                        "phone": "+49 3012 3456",
                        "company": "Beispiel GmbH",
                        "website": "https://beispiel.de",
                        "employees": "11-50",
                        "street": "Musterstraße 1",
                        "postal_code": "10115",
                        "city": "Berlin",
                        "country": "DE",
                        "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                        "linkedin_network_distance": "DISTANCE_2",
                        "status": "open",
                        "stage": "cold",
                        "outreach_status": "Ausstehend",
                        "score": 15,
                        "lead_source": "api",
                        "source_details": "Messe Köln 2026",
                        "notes": null,
                        "assigned_user_id": null,
                        "show_in_crm": false,
                        "crm_only": false,
                        "is_priority": false,
                        "do_not_contact": false,
                        "meeting_scheduled_at": null,
                        "meeting_type": null,
                        "next_action": null,
                        "next_action_at": null,
                        "landing_page_url": null,
                        "personalized_video_url": null,
                        "personalized_video_thumbnail": null,
                        "landingpage_url_qrcode": null,
                        "utm_source": null,
                        "utm_medium": null,
                        "utm_campaign": null,
                        "utm_content": null,
                        "utm_term": null,
                        "last_activity_at": "2026-10-18T09:12:00.000Z",
                        "archived_at": null,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read"
      },
      "patch": {
        "operationId": "updateLead",
        "tags": [
          "Leads"
        ],
        "summary": "Lead ändern",
        "description": "Nur übergebene Felder werden geändert. `null` leert ein Feld. Gesperrte Felder (score, stage, do_not_contact …) sind nur lesbar. Eine neue E-Mail oder LinkedIn-URL, die schon ein anderer Lead nutzt, ergibt 409 mit `existing_id`; bei LinkedIn zählt dieselbe Person in jeder Schreibweise wie bei POST /v1/leads. Eine andere Schreibweise des eigenen Profils ist kein Konflikt.\n\n**Berechtigung:** `write:leads`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "examples": [
                  {
                    "status": "interested",
                    "next_action": "proposal",
                    "next_action_at": "2026-10-21T09:00:00+02:00"
                  }
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "ID des Leads",
                    "readOnly": true,
                    "format": "uuid"
                  },
                  "list_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Liste, in der der Lead steht",
                    "format": "uuid"
                  },
                  "campaign_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Kampagne, der der Lead zugeordnet ist (Zuordnung über /v1/campaigns/{id}/leads)",
                    "readOnly": true,
                    "format": "uuid"
                  },
                  "company_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Verknüpfte CRM-Firma",
                    "readOnly": true,
                    "format": "uuid"
                  },
                  "salutation": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Anrede: Herr, Frau, Divers oder Unbekannt",
                    "enum": [
                      "Herr",
                      "Frau",
                      "Divers",
                      "Unbekannt",
                      null
                    ]
                  },
                  "academic_title": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Akademischer Titel, z. B. Dr.",
                    "maxLength": 50
                  },
                  "first_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Vorname, in Texten der Platzhalter {{first_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit last_name Pflicht",
                    "maxLength": 200
                  },
                  "last_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Nachname, in Texten der Platzhalter {{last_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit first_name Pflicht",
                    "maxLength": 200
                  },
                  "title": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Position im Unternehmen",
                    "maxLength": 300
                  },
                  "headline": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "LinkedIn-Headline",
                    "maxLength": 500
                  },
                  "email": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "E-Mail-Adresse, wird klein geschrieben gespeichert. Nutzt ein anderer Lead im Konto dieselbe Adresse (Groß/Klein egal), ist es eine Dublette: einzeln 409, in der Sammel-Anlage status duplicate",
                    "format": "email",
                    "maxLength": 320
                  },
                  "email_status": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Ergebnis der E-Mail-Prüfung",
                    "readOnly": true
                  },
                  "phone": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Wird wie in der App ins internationale Format gebracht, z. B. +49 3012 3456",
                    "maxLength": 50
                  },
                  "company": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Firmenname, in Texten der Platzhalter {{company}}",
                    "maxLength": 300
                  },
                  "website": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Website der Firma, z. B. https://beispiel.de. Videos mit scrollender Website (POST /v1/leads/{id}/video) zeigen diese Seite",
                    "maxLength": 500
                  },
                  "employees": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Unternehmensgröße, z. B. 11-50",
                    "maxLength": 50
                  },
                  "street": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Straße und Hausnummer",
                    "maxLength": 300
                  },
                  "postal_code": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Postleitzahl",
                    "maxLength": 20
                  },
                  "city": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Ort, in Texten der Platzhalter {{city}}",
                    "maxLength": 200
                  },
                  "country": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Land, wird zu ISO-Code normalisiert (DE, AT, CH …)",
                    "maxLength": 100
                  },
                  "linkedin_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "LinkedIn-Profil-URL",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "linkedin_network_distance": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Kontaktgrad zum verbundenen LinkedIn-Konto",
                    "readOnly": true
                  },
                  "status": {
                    "type": "string",
                    "description": "Vertriebsstatus",
                    "enum": [
                      "open",
                      "contacted",
                      "not_reached",
                      "interested",
                      "qualified",
                      "follow_up",
                      "booked",
                      "won",
                      "lost",
                      "disqualified",
                      "opt_out",
                      "archived"
                    ]
                  },
                  "stage": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Temperatur aus dem Scoring: cold, warm, hot",
                    "readOnly": true
                  },
                  "outreach_status": {
                    "type": "string",
                    "description": "Outreach-Status: Ausstehend (Standard), Brief (ein Brief ist in Produktion), Abgemeldet (bei Status opt_out), daneben Email, Linkedin, Beendet, Warten. LinkedIn-Kampagnen ändern ihn nicht, ihren Stand je Lead liefert GET /v1/campaigns/{id}/leads",
                    "readOnly": true,
                    "enum": [
                      "Ausstehend",
                      "Brief",
                      "Email",
                      "Linkedin",
                      "Beendet",
                      "Warten",
                      "Abgemeldet"
                    ]
                  },
                  "score": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "Lead-Score 0 bis 100",
                    "readOnly": true
                  },
                  "lead_source": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Herkunft. System: lead_scout, lead_finder, csv_import, api, manual, webhook; eigene Werte aus den Einstellungen",
                    "maxLength": 100
                  },
                  "source_details": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Freitext zur Herkunft, z. B. Messe Köln 2026",
                    "maxLength": 1000
                  },
                  "notes": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Freitext-Notiz am Lead",
                    "maxLength": 10000
                  },
                  "assigned_user_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zuständiges Team-Mitglied (siehe /v1/team)",
                    "format": "uuid"
                  },
                  "show_in_crm": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Im CRM anzeigen"
                  },
                  "crm_only": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Markierung aus dem CRM-Modul, Standard false. Über die API nicht änderbar",
                    "readOnly": true
                  },
                  "is_priority": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Als Priorität markiert. Die App sortiert solche Leads bei Wiedervorlagen und unter „Nächster Lead“ nach vorn"
                  },
                  "do_not_contact": {
                    "type": [
                      "boolean",
                      "null"
                    ],
                    "description": "Gesperrt für jede Ansprache",
                    "readOnly": true
                  },
                  "meeting_scheduled_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt des vereinbarten Termins. Eintragen wie in der App (Art, optional Status booked) über PUT /v1/leads/{id}/meeting",
                    "format": "date-time"
                  },
                  "meeting_type": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Art des Termins: setting, closing, demo oder other",
                    "enum": [
                      "setting",
                      "closing",
                      "demo",
                      "other",
                      null
                    ]
                  },
                  "next_action": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Nächster Schritt: call, email, meeting, proposal oder wait (Zeitpunkt in next_action_at)",
                    "enum": [
                      "call",
                      "email",
                      "meeting",
                      "proposal",
                      "wait",
                      null
                    ]
                  },
                  "next_action_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt für den nächsten Schritt aus next_action",
                    "format": "date-time"
                  },
                  "landing_page_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "URL der personalisierten Landingpage des Leads, null solange keine erzeugt wurde",
                    "readOnly": true
                  },
                  "personalized_video_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "URL des personalisierten Videos, null solange keins erzeugt wurde (POST /v1/leads/{id}/video)",
                    "readOnly": true
                  },
                  "personalized_video_thumbnail": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "URL des Vorschaubilds zum personalisierten Video, null ohne Video",
                    "readOnly": true
                  },
                  "landingpage_url_qrcode": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "URL eines QR-Code-Bilds, das auf landing_page_url zeigt (z. B. für Briefe), null solange keiner erzeugt wurde",
                    "readOnly": true
                  },
                  "utm_source": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_source der Herkunft (Quelle, z. B. newsletter)",
                    "maxLength": 200
                  },
                  "utm_medium": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_medium der Herkunft (Medium, z. B. email)",
                    "maxLength": 200
                  },
                  "utm_campaign": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_campaign der Herkunft (Name der Werbekampagne)",
                    "maxLength": 200
                  },
                  "utm_content": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_content der Herkunft (Anzeige oder Link)",
                    "maxLength": 200
                  },
                  "utm_term": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "UTM-Parameter utm_term der Herkunft (Suchbegriff)",
                    "maxLength": 200
                  },
                  "last_activity_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt der letzten Aktivität am Lead (ISO 8601, UTC), null ohne Aktivität",
                    "readOnly": true,
                    "format": "date-time"
                  },
                  "archived_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt der Archivierung (ISO 8601, UTC), null bei aktiven Leads. GET /v1/leads zeigt archivierte nur mit include_archived",
                    "readOnly": true,
                    "format": "date-time"
                  },
                  "created_at": {
                    "type": "string",
                    "description": "Anlagezeitpunkt (ISO 8601, UTC)",
                    "readOnly": true,
                    "format": "date-time"
                  },
                  "updated_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Zeitpunkt der letzten Änderung (ISO 8601, UTC)",
                    "readOnly": true,
                    "format": "date-time"
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "status": "interested",
                    "next_action": "proposal",
                    "next_action_at": "2026-10-21T09:00:00+02:00"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "campaign_id": null,
                          "company_id": null,
                          "salutation": "Herr",
                          "academic_title": "Dr.",
                          "first_name": "Max",
                          "last_name": "Mustermann",
                          "title": "Geschäftsführer",
                          "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                          "email": "max.mustermann@beispiel.de",
                          "email_status": null,
                          "phone": "+49 3012 3456",
                          "company": "Beispiel GmbH",
                          "website": "https://beispiel.de",
                          "employees": "11-50",
                          "street": "Musterstraße 1",
                          "postal_code": "10115",
                          "city": "Berlin",
                          "country": "DE",
                          "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                          "linkedin_network_distance": "DISTANCE_2",
                          "status": "open",
                          "stage": "cold",
                          "outreach_status": "Ausstehend",
                          "score": 15,
                          "lead_source": "api",
                          "source_details": "Messe Köln 2026",
                          "notes": null,
                          "assigned_user_id": null,
                          "show_in_crm": false,
                          "crm_only": false,
                          "is_priority": false,
                          "do_not_contact": false,
                          "meeting_scheduled_at": null,
                          "meeting_type": null,
                          "next_action": null,
                          "next_action_at": null,
                          "landing_page_url": null,
                          "personalized_video_url": null,
                          "personalized_video_thumbnail": null,
                          "landingpage_url_qrcode": null,
                          "utm_source": null,
                          "utm_medium": null,
                          "utm_campaign": null,
                          "utm_content": null,
                          "utm_term": null,
                          "last_activity_at": "2026-10-18T09:12:00.000Z",
                          "archived_at": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "list_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Liste, in der der Lead steht",
                          "format": "uuid"
                        },
                        "campaign_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kampagne, der der Lead zugeordnet ist (Zuordnung über /v1/campaigns/{id}/leads)",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "company_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Verknüpfte CRM-Firma",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "salutation": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Anrede: Herr, Frau, Divers oder Unbekannt",
                          "enum": [
                            "Herr",
                            "Frau",
                            "Divers",
                            "Unbekannt",
                            null
                          ]
                        },
                        "academic_title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Akademischer Titel, z. B. Dr.",
                          "maxLength": 50
                        },
                        "first_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorname, in Texten der Platzhalter {{first_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit last_name Pflicht",
                          "maxLength": 200
                        },
                        "last_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nachname, in Texten der Platzhalter {{last_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit first_name Pflicht",
                          "maxLength": 200
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Position im Unternehmen",
                          "maxLength": 300
                        },
                        "headline": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Headline",
                          "maxLength": 500
                        },
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "E-Mail-Adresse, wird klein geschrieben gespeichert. Nutzt ein anderer Lead im Konto dieselbe Adresse (Groß/Klein egal), ist es eine Dublette: einzeln 409, in der Sammel-Anlage status duplicate",
                          "format": "email",
                          "maxLength": 320
                        },
                        "email_status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ergebnis der E-Mail-Prüfung",
                          "readOnly": true
                        },
                        "phone": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Wird wie in der App ins internationale Format gebracht, z. B. +49 3012 3456",
                          "maxLength": 50
                        },
                        "company": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Firmenname, in Texten der Platzhalter {{company}}",
                          "maxLength": 300
                        },
                        "website": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Website der Firma, z. B. https://beispiel.de. Videos mit scrollender Website (POST /v1/leads/{id}/video) zeigen diese Seite",
                          "maxLength": 500
                        },
                        "employees": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Unternehmensgröße, z. B. 11-50",
                          "maxLength": 50
                        },
                        "street": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Straße und Hausnummer",
                          "maxLength": 300
                        },
                        "postal_code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Postleitzahl",
                          "maxLength": 20
                        },
                        "city": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ort, in Texten der Platzhalter {{city}}",
                          "maxLength": 200
                        },
                        "country": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Land, wird zu ISO-Code normalisiert (DE, AT, CH …)",
                          "maxLength": 100
                        },
                        "linkedin_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Profil-URL",
                          "format": "uri",
                          "maxLength": 2048
                        },
                        "linkedin_network_distance": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kontaktgrad zum verbundenen LinkedIn-Konto",
                          "readOnly": true
                        },
                        "status": {
                          "type": "string",
                          "description": "Vertriebsstatus",
                          "enum": [
                            "open",
                            "contacted",
                            "not_reached",
                            "interested",
                            "qualified",
                            "follow_up",
                            "booked",
                            "won",
                            "lost",
                            "disqualified",
                            "opt_out",
                            "archived"
                          ]
                        },
                        "stage": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Temperatur aus dem Scoring: cold, warm, hot",
                          "readOnly": true
                        },
                        "outreach_status": {
                          "type": "string",
                          "description": "Outreach-Status: Ausstehend (Standard), Brief (ein Brief ist in Produktion), Abgemeldet (bei Status opt_out), daneben Email, Linkedin, Beendet, Warten. LinkedIn-Kampagnen ändern ihn nicht, ihren Stand je Lead liefert GET /v1/campaigns/{id}/leads",
                          "readOnly": true,
                          "enum": [
                            "Ausstehend",
                            "Brief",
                            "Email",
                            "Linkedin",
                            "Beendet",
                            "Warten",
                            "Abgemeldet"
                          ]
                        },
                        "score": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Lead-Score 0 bis 100",
                          "readOnly": true
                        },
                        "lead_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Herkunft. System: lead_scout, lead_finder, csv_import, api, manual, webhook; eigene Werte aus den Einstellungen",
                          "maxLength": 100
                        },
                        "source_details": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext zur Herkunft, z. B. Messe Köln 2026",
                          "maxLength": 1000
                        },
                        "notes": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext-Notiz am Lead",
                          "maxLength": 10000
                        },
                        "assigned_user_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zuständiges Team-Mitglied (siehe /v1/team)",
                          "format": "uuid"
                        },
                        "show_in_crm": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Im CRM anzeigen"
                        },
                        "crm_only": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Markierung aus dem CRM-Modul, Standard false. Über die API nicht änderbar",
                          "readOnly": true
                        },
                        "is_priority": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Als Priorität markiert. Die App sortiert solche Leads bei Wiedervorlagen und unter „Nächster Lead“ nach vorn"
                        },
                        "do_not_contact": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Gesperrt für jede Ansprache",
                          "readOnly": true
                        },
                        "meeting_scheduled_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt des vereinbarten Termins. Eintragen wie in der App (Art, optional Status booked) über PUT /v1/leads/{id}/meeting",
                          "format": "date-time"
                        },
                        "meeting_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Art des Termins: setting, closing, demo oder other",
                          "enum": [
                            "setting",
                            "closing",
                            "demo",
                            "other",
                            null
                          ]
                        },
                        "next_action": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nächster Schritt: call, email, meeting, proposal oder wait (Zeitpunkt in next_action_at)",
                          "enum": [
                            "call",
                            "email",
                            "meeting",
                            "proposal",
                            "wait",
                            null
                          ]
                        },
                        "next_action_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt für den nächsten Schritt aus next_action",
                          "format": "date-time"
                        },
                        "landing_page_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL der personalisierten Landingpage des Leads, null solange keine erzeugt wurde",
                          "readOnly": true
                        },
                        "personalized_video_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL des personalisierten Videos, null solange keins erzeugt wurde (POST /v1/leads/{id}/video)",
                          "readOnly": true
                        },
                        "personalized_video_thumbnail": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL des Vorschaubilds zum personalisierten Video, null ohne Video",
                          "readOnly": true
                        },
                        "landingpage_url_qrcode": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL eines QR-Code-Bilds, das auf landing_page_url zeigt (z. B. für Briefe), null solange keiner erzeugt wurde",
                          "readOnly": true
                        },
                        "utm_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_source der Herkunft (Quelle, z. B. newsletter)",
                          "maxLength": 200
                        },
                        "utm_medium": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_medium der Herkunft (Medium, z. B. email)",
                          "maxLength": 200
                        },
                        "utm_campaign": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_campaign der Herkunft (Name der Werbekampagne)",
                          "maxLength": 200
                        },
                        "utm_content": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_content der Herkunft (Anzeige oder Link)",
                          "maxLength": 200
                        },
                        "utm_term": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_term der Herkunft (Suchbegriff)",
                          "maxLength": 200
                        },
                        "last_activity_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Aktivität am Lead (ISO 8601, UTC), null ohne Aktivität",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "archived_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der Archivierung (ISO 8601, UTC), null bei aktiven Leads. GET /v1/leads zeigt archivierte nur mit include_archived",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Anlagezeitpunkt (ISO 8601, UTC)",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung (ISO 8601, UTC)",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "campaign_id": null,
                        "company_id": null,
                        "salutation": "Herr",
                        "academic_title": "Dr.",
                        "first_name": "Max",
                        "last_name": "Mustermann",
                        "title": "Geschäftsführer",
                        "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                        "email": "max.mustermann@beispiel.de",
                        "email_status": null,
                        "phone": "+49 3012 3456",
                        "company": "Beispiel GmbH",
                        "website": "https://beispiel.de",
                        "employees": "11-50",
                        "street": "Musterstraße 1",
                        "postal_code": "10115",
                        "city": "Berlin",
                        "country": "DE",
                        "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                        "linkedin_network_distance": "DISTANCE_2",
                        "status": "interested",
                        "stage": "cold",
                        "outreach_status": "Ausstehend",
                        "score": 15,
                        "lead_source": "api",
                        "source_details": "Messe Köln 2026",
                        "notes": null,
                        "assigned_user_id": null,
                        "show_in_crm": false,
                        "crm_only": false,
                        "is_priority": false,
                        "do_not_contact": false,
                        "meeting_scheduled_at": null,
                        "meeting_type": null,
                        "next_action": "proposal",
                        "next_action_at": "2026-10-21T07:00:00.000Z",
                        "landing_page_url": null,
                        "personalized_video_url": null,
                        "personalized_video_thumbnail": null,
                        "landingpage_url_qrcode": null,
                        "utm_source": null,
                        "utm_medium": null,
                        "utm_campaign": null,
                        "utm_content": null,
                        "utm_term": null,
                        "last_activity_at": "2026-10-18T09:12:00.000Z",
                        "archived_at": null,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:leads",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      },
      "delete": {
        "operationId": "deleteLead",
        "tags": [
          "Leads"
        ],
        "summary": "Lead endgültig löschen",
        "description": "Löscht den Lead mit allen Daten (Aktivitäten, Landingpage, Video, CRM-Verknüpfungen), wie das Löschen in der App. Nicht umkehrbar. Braucht den Scope delete:leads.\n\n**Berechtigung:** `delete:leads` (sensibel, wird nie automatisch vergeben)\n\n**Recht in dealsky:** `crm.leads.delete` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Löscht endgültig. Nicht umkehrbar.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "Immer true, wenn der Lead gelöscht wurde"
                        },
                        "id": {
                          "type": "string",
                          "description": "ID des gelöschten Leads",
                          "format": "uuid"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "deleted": true,
                        "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "delete:leads",
        "x-dealsky-permission": "crm.leads.delete",
        "x-dealsky-risk": "destructive"
      }
    },
    "/v1/leads/bulk": {
      "post": {
        "operationId": "createLeadsBulk",
        "tags": [
          "Leads"
        ],
        "summary": "Bis zu 100 Leads auf einmal anlegen",
        "description": "Legt bis zu 100 Leads in einem Aufruf an, mit denselben Feldern und derselben Prüfung wie POST /v1/leads (Pflichtangaben, Telefon mit Ländervorwahl, Land als ISO-Code, Herkunft, Liste und Team-Mitglied des eigenen Kontos). Eine fehlerhafte Zeile hält die anderen nicht auf: `results` nennt für jede Zeile in Eingabe-Reihenfolge `created`, `duplicate`, `invalid` (mit `errors`) oder bei `on_duplicate: \"update\"` auch `updated`. Alle neuen Leads werden in einem Schritt geschrieben.\n\n`list_id` oben gilt für jede Zeile ohne eigenes `list_id`; die Liste muss zum eigenen Konto gehören, sonst 400 und es wird nichts geschrieben.\n\n**Dubletten** wie bei POST /v1/leads: gleiche E-Mail (Groß/Klein egal) oder dieselbe LinkedIn-Person im Konto (jede Schreibweise der Profil-URL, siehe dort), dazu dieselbe Angabe weiter oben in derselben Anfrage, auch in anderer Schreibweise (`duplicate_of_index`, die erste Zeile gewinnt). `existing_id` ist der älteste passende Lead.\n\n**on_duplicate:** `skip` (Standard) überspringt vorhandene Personen, wie der CSV-Import der App, der bekannte Personen nie überschreibt. `update` füllt beim vorhandenen Lead nur Felder, die dort leer sind, wie das Zusammenführen von Dubletten in der App. Nichts wird überschrieben, Liste und Status bleiben. Wer gezielt überschreiben will, nutzt PATCH /v1/leads/{id} mit `existing_id`.\n\nNicht enthalten, wie bei POST /v1/leads: Der CSV-Import der App sortiert zusätzlich Kontakte auf der Ausschlussliste aus, startet danach die Anreden-Erkennung und legt bei CRM-Leads die Firma im CRM an.\n\nBody höchstens 1 MB (für 100 Leads reicht das reichlich). Mit Test-Key kommt dieselbe Auswertung je Zeile, geschrieben wird nichts und neue Zeilen haben keine `id`.\n\n**Berechtigung:** `write:leads`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "list_id": {
                    "type": "string",
                    "description": "Liste für alle Zeilen ohne eigenes list_id",
                    "format": "uuid"
                  },
                  "on_duplicate": {
                    "type": "string",
                    "description": "skip (Standard): vorhandene Leads bleiben unverändert. update: nur leere Felder des vorhandenen Leads füllen",
                    "enum": [
                      "skip",
                      "update"
                    ]
                  },
                  "leads": {
                    "type": "array",
                    "description": "1 bis 100 Leads",
                    "items": {
                      "type": "object",
                      "description": "Felder und Prüfung wie bei POST /v1/leads. list_id ist Pflicht, außer es steht oben ein list_id für alle Zeilen.",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "list_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Liste, in der der Lead steht",
                          "format": "uuid"
                        },
                        "campaign_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kampagne, der der Lead zugeordnet ist (Zuordnung über /v1/campaigns/{id}/leads)",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "company_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Verknüpfte CRM-Firma",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "salutation": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Anrede: Herr, Frau, Divers oder Unbekannt",
                          "enum": [
                            "Herr",
                            "Frau",
                            "Divers",
                            "Unbekannt",
                            null
                          ]
                        },
                        "academic_title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Akademischer Titel, z. B. Dr.",
                          "maxLength": 50
                        },
                        "first_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorname, in Texten der Platzhalter {{first_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit last_name Pflicht",
                          "maxLength": 200
                        },
                        "last_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nachname, in Texten der Platzhalter {{last_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit first_name Pflicht",
                          "maxLength": 200
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Position im Unternehmen",
                          "maxLength": 300
                        },
                        "headline": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Headline",
                          "maxLength": 500
                        },
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "E-Mail-Adresse, wird klein geschrieben gespeichert. Nutzt ein anderer Lead im Konto dieselbe Adresse (Groß/Klein egal), ist es eine Dublette: einzeln 409, in der Sammel-Anlage status duplicate",
                          "format": "email",
                          "maxLength": 320
                        },
                        "email_status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ergebnis der E-Mail-Prüfung",
                          "readOnly": true
                        },
                        "phone": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Wird wie in der App ins internationale Format gebracht, z. B. +49 3012 3456",
                          "maxLength": 50
                        },
                        "company": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Firmenname, in Texten der Platzhalter {{company}}",
                          "maxLength": 300
                        },
                        "website": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Website der Firma, z. B. https://beispiel.de. Videos mit scrollender Website (POST /v1/leads/{id}/video) zeigen diese Seite",
                          "maxLength": 500
                        },
                        "employees": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Unternehmensgröße, z. B. 11-50",
                          "maxLength": 50
                        },
                        "street": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Straße und Hausnummer",
                          "maxLength": 300
                        },
                        "postal_code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Postleitzahl",
                          "maxLength": 20
                        },
                        "city": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ort, in Texten der Platzhalter {{city}}",
                          "maxLength": 200
                        },
                        "country": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Land, wird zu ISO-Code normalisiert (DE, AT, CH …)",
                          "maxLength": 100
                        },
                        "linkedin_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Profil-URL",
                          "format": "uri",
                          "maxLength": 2048
                        },
                        "linkedin_network_distance": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kontaktgrad zum verbundenen LinkedIn-Konto",
                          "readOnly": true
                        },
                        "status": {
                          "type": "string",
                          "description": "Standard: open",
                          "enum": [
                            "open",
                            "contacted",
                            "not_reached",
                            "interested",
                            "qualified",
                            "follow_up",
                            "booked",
                            "won",
                            "lost",
                            "disqualified",
                            "opt_out",
                            "archived"
                          ]
                        },
                        "stage": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Temperatur aus dem Scoring: cold, warm, hot",
                          "readOnly": true
                        },
                        "outreach_status": {
                          "type": "string",
                          "description": "Outreach-Status: Ausstehend (Standard), Brief (ein Brief ist in Produktion), Abgemeldet (bei Status opt_out), daneben Email, Linkedin, Beendet, Warten. LinkedIn-Kampagnen ändern ihn nicht, ihren Stand je Lead liefert GET /v1/campaigns/{id}/leads",
                          "readOnly": true,
                          "enum": [
                            "Ausstehend",
                            "Brief",
                            "Email",
                            "Linkedin",
                            "Beendet",
                            "Warten",
                            "Abgemeldet"
                          ]
                        },
                        "score": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Lead-Score 0 bis 100",
                          "readOnly": true
                        },
                        "lead_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Herkunft. System: lead_scout, lead_finder, csv_import, api, manual, webhook; eigene Werte aus den Einstellungen",
                          "maxLength": 100
                        },
                        "source_details": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext zur Herkunft, z. B. Messe Köln 2026",
                          "maxLength": 1000
                        },
                        "notes": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext-Notiz am Lead",
                          "maxLength": 10000
                        },
                        "assigned_user_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zuständiges Team-Mitglied (siehe /v1/team)",
                          "format": "uuid"
                        },
                        "show_in_crm": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Im CRM anzeigen"
                        },
                        "crm_only": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Markierung aus dem CRM-Modul, Standard false. Über die API nicht änderbar",
                          "readOnly": true
                        },
                        "is_priority": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Als Priorität markiert. Die App sortiert solche Leads bei Wiedervorlagen und unter „Nächster Lead“ nach vorn"
                        },
                        "do_not_contact": {
                          "type": [
                            "boolean",
                            "null"
                          ],
                          "description": "Gesperrt für jede Ansprache",
                          "readOnly": true
                        },
                        "meeting_scheduled_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt des vereinbarten Termins. Eintragen wie in der App (Art, optional Status booked) über PUT /v1/leads/{id}/meeting",
                          "format": "date-time"
                        },
                        "meeting_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Art des Termins: setting, closing, demo oder other",
                          "enum": [
                            "setting",
                            "closing",
                            "demo",
                            "other",
                            null
                          ]
                        },
                        "next_action": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nächster Schritt: call, email, meeting, proposal oder wait (Zeitpunkt in next_action_at)",
                          "enum": [
                            "call",
                            "email",
                            "meeting",
                            "proposal",
                            "wait",
                            null
                          ]
                        },
                        "next_action_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt für den nächsten Schritt aus next_action",
                          "format": "date-time"
                        },
                        "landing_page_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL der personalisierten Landingpage des Leads, null solange keine erzeugt wurde",
                          "readOnly": true
                        },
                        "personalized_video_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL des personalisierten Videos, null solange keins erzeugt wurde (POST /v1/leads/{id}/video)",
                          "readOnly": true
                        },
                        "personalized_video_thumbnail": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL des Vorschaubilds zum personalisierten Video, null ohne Video",
                          "readOnly": true
                        },
                        "landingpage_url_qrcode": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "URL eines QR-Code-Bilds, das auf landing_page_url zeigt (z. B. für Briefe), null solange keiner erzeugt wurde",
                          "readOnly": true
                        },
                        "utm_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_source der Herkunft (Quelle, z. B. newsletter)",
                          "maxLength": 200
                        },
                        "utm_medium": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_medium der Herkunft (Medium, z. B. email)",
                          "maxLength": 200
                        },
                        "utm_campaign": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_campaign der Herkunft (Name der Werbekampagne)",
                          "maxLength": 200
                        },
                        "utm_content": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_content der Herkunft (Anzeige oder Link)",
                          "maxLength": 200
                        },
                        "utm_term": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "UTM-Parameter utm_term der Herkunft (Suchbegriff)",
                          "maxLength": 200
                        },
                        "last_activity_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Aktivität am Lead (ISO 8601, UTC), null ohne Aktivität",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "archived_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der Archivierung (ISO 8601, UTC), null bei aktiven Leads. GET /v1/leads zeigt archivierte nur mit include_archived",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Anlagezeitpunkt (ISO 8601, UTC)",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung (ISO 8601, UTC)",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "minItems": 1,
                    "maxItems": 100
                  }
                },
                "required": [
                  "leads"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Gemischte Zeilen: neu, Dublette im Konto, Dublette in der Anfrage, ungültig",
                  "value": {
                    "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                    "on_duplicate": "skip",
                    "leads": [
                      {
                        "first_name": "Erika",
                        "last_name": "Beispiel",
                        "email": "erika@beispiel.de",
                        "company": "Beispiel GmbH",
                        "phone": "030 987654"
                      },
                      {
                        "first_name": "Max",
                        "last_name": "Mustermann",
                        "email": "max.mustermann@beispiel.de"
                      },
                      {
                        "first_name": "Erika",
                        "last_name": "Beispiel",
                        "email": "ERIKA@beispiel.de"
                      },
                      {
                        "first_name": "Jonas",
                        "company": "Muster AG"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "summary": {
                          "type": "object",
                          "description": "Zählung der Ergebnisse je status",
                          "properties": {
                            "total": {
                              "type": "integer",
                              "description": "Zahl der Zeilen in leads"
                            },
                            "created": {
                              "type": "integer",
                              "description": "Zeilen mit status created"
                            },
                            "updated": {
                              "type": "integer",
                              "description": "Zeilen mit status updated"
                            },
                            "duplicate": {
                              "type": "integer",
                              "description": "Zeilen mit status duplicate"
                            },
                            "invalid": {
                              "type": "integer",
                              "description": "Zeilen mit status invalid"
                            }
                          },
                          "additionalProperties": false
                        },
                        "results": {
                          "type": "array",
                          "description": "Eine Zeile je Eingabe, in derselben Reihenfolge",
                          "items": {
                            "type": "object",
                            "properties": {
                              "index": {
                                "type": "integer",
                                "description": "Position in leads, ab 0"
                              },
                              "status": {
                                "type": "string",
                                "description": "Ergebnis der Zeile: created (neu angelegt), updated (vorhandener Lead ergänzt, nur bei on_duplicate update), duplicate (Dublette, nicht angelegt), invalid (Prüfung fehlgeschlagen)",
                                "enum": [
                                  "created",
                                  "updated",
                                  "duplicate",
                                  "invalid"
                                ]
                              },
                              "id": {
                                "type": "string",
                                "description": "Nur bei created: ID des neuen Leads (mit Test-Key nicht gesetzt)",
                                "format": "uuid"
                              },
                              "existing_id": {
                                "type": "string",
                                "description": "duplicate oder updated: der vorhandene Lead im Konto",
                                "format": "uuid"
                              },
                              "duplicate_of_index": {
                                "type": "integer",
                                "description": "duplicate innerhalb dieser Anfrage: Position der ersten Zeile mit derselben Angabe"
                              },
                              "field": {
                                "type": "string",
                                "description": "Woran die Dublette erkannt wurde",
                                "enum": [
                                  "email",
                                  "linkedin_url"
                                ]
                              },
                              "updated_fields": {
                                "type": "array",
                                "description": "Nur bei updated: die vorher leeren Felder, die gefüllt wurden",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "errors": {
                                "type": "array",
                                "description": "Nur bei invalid: Feld und Grund",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "field": {
                                      "type": "string",
                                      "description": "Betroffenes Feld der Zeile, (zeile) wenn die ganze Zeile scheiterte"
                                    },
                                    "message": {
                                      "type": "string",
                                      "description": "Grund auf Deutsch"
                                    }
                                  },
                                  "additionalProperties": false
                                }
                              }
                            },
                            "additionalProperties": false
                          }
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Gemischte Zeilen: neu, Dublette im Konto, Dublette in der Anfrage, ungültig",
                    "value": {
                      "ok": true,
                      "data": {
                        "summary": {
                          "total": 4,
                          "created": 1,
                          "updated": 0,
                          "duplicate": 2,
                          "invalid": 1
                        },
                        "results": [
                          {
                            "index": 0,
                            "status": "created",
                            "id": "7d1e2f3a-4b5c-4d6e-8f70-81a2b3c4d5e6"
                          },
                          {
                            "index": 1,
                            "status": "duplicate",
                            "field": "email",
                            "existing_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10"
                          },
                          {
                            "index": 2,
                            "status": "duplicate",
                            "field": "email",
                            "duplicate_of_index": 0
                          },
                          {
                            "index": 3,
                            "status": "invalid",
                            "errors": [
                              {
                                "field": "email",
                                "message": "oder linkedin_url oder first_name + last_name"
                              }
                            ]
                          }
                        ]
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:leads",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/leads/{id}/activities": {
      "get": {
        "operationId": "listLeadActivities",
        "tags": [
          "Leads"
        ],
        "summary": "Verlauf eines Leads",
        "description": "Aktivitäten wie gesendete LinkedIn-Nachrichten, Antworten, Anrufe, Notizen und Statuswechsel, neueste zuerst.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "channel",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Aktivitäten dieses Kanals",
              "enum": [
                "email",
                "linkedin",
                "phone",
                "direct_mail",
                "web",
                "landingpage"
              ]
            },
            "description": "Nur Aktivitäten dieses Kanals"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Aktivitäten dieser Art, exakter Wert wie im Feld type, z. B. linkedin_message_sent",
              "maxLength": 100
            },
            "description": "Nur Aktivitäten dieser Art, exakter Wert wie im Feld type, z. B. linkedin_message_sent"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Aktivität",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string",
                            "description": "Art der Aktivität, z. B. linkedin_message_sent, call, note"
                          },
                          "channel": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kanal: email, linkedin, phone, direct_mail, web oder landingpage, null wenn keiner zugeordnet ist"
                          },
                          "subject": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Betreff oder Kurztitel, null wenn die Aktivität keinen hat"
                          },
                          "content": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Inhalt, z. B. Nachrichtentext oder Notiz, null wenn leer"
                          },
                          "campaign_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kampagne, aus der die Aktivität stammt, null ohne Kampagne",
                            "format": "uuid"
                          },
                          "metadata": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Zusatzangaben je Art als freies JSON-Objekt, Schlüssel hängen von type ab",
                            "additionalProperties": true
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt der Aktivität (ISO 8601, UTC)",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "9c7a1b2d-4e5f-4a6b-8c9d-0e1f2a3b4c5d",
                          "type": "linkedin_message_sent",
                          "channel": "linkedin",
                          "subject": null,
                          "content": "Hallo Herr Mustermann, …",
                          "campaign_id": null,
                          "metadata": {},
                          "created_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/leads/hot": {
      "get": {
        "operationId": "listHotLeads",
        "tags": [
          "Leads"
        ],
        "summary": "Heiße Leads",
        "description": "Leads, deren Score die Schwelle „heiß“ des Kontos erreicht, wie der Schnellfilter „Hot“ in der Leads-Tabelle und die Kachel „Heiße Leads“ im Dashboard: Score mindestens die Hot-Schwelle aus den Einstellungen (Lead-Scoring, Standard 76), ohne archivierte Leads und ohne Demo-Leads.\n\nHöchster Score zuerst, bei gleichem Score die jüngste Aktivität zuerst. Felder wie GET /v1/leads. Die Schwellen und die Wärme eines einzelnen Leads nennt GET /v1/leads/{id}/engagement.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "list_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Leads dieser Liste",
              "format": "uuid"
            },
            "description": "Nur Leads dieser Liste"
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Leads, die dieser Kampagne zugeordnet sind (wie bei GET /v1/leads)",
              "format": "uuid"
            },
            "description": "Nur Leads, die dieser Kampagne zugeordnet sind (wie bei GET /v1/leads)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                            "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                            "campaign_id": null,
                            "company_id": null,
                            "salutation": "Herr",
                            "academic_title": "Dr.",
                            "first_name": "Max",
                            "last_name": "Mustermann",
                            "title": "Geschäftsführer",
                            "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                            "email": "max.mustermann@beispiel.de",
                            "email_status": null,
                            "phone": "+49 3012 3456",
                            "company": "Beispiel GmbH",
                            "website": "https://beispiel.de",
                            "employees": "11-50",
                            "street": "Musterstraße 1",
                            "postal_code": "10115",
                            "city": "Berlin",
                            "country": "DE",
                            "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                            "linkedin_network_distance": "DISTANCE_2",
                            "status": "open",
                            "stage": "cold",
                            "outreach_status": "Ausstehend",
                            "score": 15,
                            "lead_source": "api",
                            "source_details": "Messe Köln 2026",
                            "notes": null,
                            "assigned_user_id": null,
                            "show_in_crm": false,
                            "crm_only": false,
                            "is_priority": false,
                            "do_not_contact": false,
                            "meeting_scheduled_at": null,
                            "meeting_type": null,
                            "next_action": null,
                            "next_action_at": null,
                            "landing_page_url": null,
                            "personalized_video_url": null,
                            "personalized_video_thumbnail": null,
                            "landingpage_url_qrcode": null,
                            "utm_source": null,
                            "utm_medium": null,
                            "utm_campaign": null,
                            "utm_content": null,
                            "utm_term": null,
                            "last_activity_at": "2026-10-18T09:12:00.000Z",
                            "archived_at": null,
                            "created_at": "2026-10-01T08:00:00.000Z",
                            "updated_at": "2026-10-18T09:12:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Leads",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "list_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Liste, in der der Lead steht",
                            "format": "uuid"
                          },
                          "campaign_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kampagne, der der Lead zugeordnet ist (Zuordnung über /v1/campaigns/{id}/leads)",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "company_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Verknüpfte CRM-Firma",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "salutation": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Anrede: Herr, Frau, Divers oder Unbekannt",
                            "enum": [
                              "Herr",
                              "Frau",
                              "Divers",
                              "Unbekannt",
                              null
                            ]
                          },
                          "academic_title": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Akademischer Titel, z. B. Dr.",
                            "maxLength": 50
                          },
                          "first_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vorname, in Texten der Platzhalter {{first_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit last_name Pflicht",
                            "maxLength": 200
                          },
                          "last_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nachname, in Texten der Platzhalter {{last_name}}. Beim Anlegen ohne email und linkedin_url zusammen mit first_name Pflicht",
                            "maxLength": 200
                          },
                          "title": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Position im Unternehmen",
                            "maxLength": 300
                          },
                          "headline": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LinkedIn-Headline",
                            "maxLength": 500
                          },
                          "email": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "E-Mail-Adresse, wird klein geschrieben gespeichert. Nutzt ein anderer Lead im Konto dieselbe Adresse (Groß/Klein egal), ist es eine Dublette: einzeln 409, in der Sammel-Anlage status duplicate",
                            "format": "email",
                            "maxLength": 320
                          },
                          "email_status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Ergebnis der E-Mail-Prüfung",
                            "readOnly": true
                          },
                          "phone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Wird wie in der App ins internationale Format gebracht, z. B. +49 3012 3456",
                            "maxLength": 50
                          },
                          "company": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Firmenname, in Texten der Platzhalter {{company}}",
                            "maxLength": 300
                          },
                          "website": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Website der Firma, z. B. https://beispiel.de. Videos mit scrollender Website (POST /v1/leads/{id}/video) zeigen diese Seite",
                            "maxLength": 500
                          },
                          "employees": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Unternehmensgröße, z. B. 11-50",
                            "maxLength": 50
                          },
                          "street": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Straße und Hausnummer",
                            "maxLength": 300
                          },
                          "postal_code": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Postleitzahl",
                            "maxLength": 20
                          },
                          "city": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Ort, in Texten der Platzhalter {{city}}",
                            "maxLength": 200
                          },
                          "country": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Land, wird zu ISO-Code normalisiert (DE, AT, CH …)",
                            "maxLength": 100
                          },
                          "linkedin_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LinkedIn-Profil-URL",
                            "format": "uri",
                            "maxLength": 2048
                          },
                          "linkedin_network_distance": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kontaktgrad zum verbundenen LinkedIn-Konto",
                            "readOnly": true
                          },
                          "status": {
                            "type": "string",
                            "description": "Vertriebsstatus",
                            "enum": [
                              "open",
                              "contacted",
                              "not_reached",
                              "interested",
                              "qualified",
                              "follow_up",
                              "booked",
                              "won",
                              "lost",
                              "disqualified",
                              "opt_out",
                              "archived"
                            ]
                          },
                          "stage": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Temperatur aus dem Scoring: cold, warm, hot",
                            "readOnly": true
                          },
                          "outreach_status": {
                            "type": "string",
                            "description": "Outreach-Status: Ausstehend (Standard), Brief (ein Brief ist in Produktion), Abgemeldet (bei Status opt_out), daneben Email, Linkedin, Beendet, Warten. LinkedIn-Kampagnen ändern ihn nicht, ihren Stand je Lead liefert GET /v1/campaigns/{id}/leads",
                            "readOnly": true,
                            "enum": [
                              "Ausstehend",
                              "Brief",
                              "Email",
                              "Linkedin",
                              "Beendet",
                              "Warten",
                              "Abgemeldet"
                            ]
                          },
                          "score": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Lead-Score 0 bis 100",
                            "readOnly": true
                          },
                          "lead_source": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Herkunft. System: lead_scout, lead_finder, csv_import, api, manual, webhook; eigene Werte aus den Einstellungen",
                            "maxLength": 100
                          },
                          "source_details": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Freitext zur Herkunft, z. B. Messe Köln 2026",
                            "maxLength": 1000
                          },
                          "notes": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Freitext-Notiz am Lead",
                            "maxLength": 10000
                          },
                          "assigned_user_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zuständiges Team-Mitglied (siehe /v1/team)",
                            "format": "uuid"
                          },
                          "show_in_crm": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Im CRM anzeigen"
                          },
                          "crm_only": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Markierung aus dem CRM-Modul, Standard false. Über die API nicht änderbar",
                            "readOnly": true
                          },
                          "is_priority": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Als Priorität markiert. Die App sortiert solche Leads bei Wiedervorlagen und unter „Nächster Lead“ nach vorn"
                          },
                          "do_not_contact": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Gesperrt für jede Ansprache",
                            "readOnly": true
                          },
                          "meeting_scheduled_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt des vereinbarten Termins. Eintragen wie in der App (Art, optional Status booked) über PUT /v1/leads/{id}/meeting",
                            "format": "date-time"
                          },
                          "meeting_type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Art des Termins: setting, closing, demo oder other",
                            "enum": [
                              "setting",
                              "closing",
                              "demo",
                              "other",
                              null
                            ]
                          },
                          "next_action": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nächster Schritt: call, email, meeting, proposal oder wait (Zeitpunkt in next_action_at)",
                            "enum": [
                              "call",
                              "email",
                              "meeting",
                              "proposal",
                              "wait",
                              null
                            ]
                          },
                          "next_action_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt für den nächsten Schritt aus next_action",
                            "format": "date-time"
                          },
                          "landing_page_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL der personalisierten Landingpage des Leads, null solange keine erzeugt wurde",
                            "readOnly": true
                          },
                          "personalized_video_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL des personalisierten Videos, null solange keins erzeugt wurde (POST /v1/leads/{id}/video)",
                            "readOnly": true
                          },
                          "personalized_video_thumbnail": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL des Vorschaubilds zum personalisierten Video, null ohne Video",
                            "readOnly": true
                          },
                          "landingpage_url_qrcode": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL eines QR-Code-Bilds, das auf landing_page_url zeigt (z. B. für Briefe), null solange keiner erzeugt wurde",
                            "readOnly": true
                          },
                          "utm_source": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_source der Herkunft (Quelle, z. B. newsletter)",
                            "maxLength": 200
                          },
                          "utm_medium": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_medium der Herkunft (Medium, z. B. email)",
                            "maxLength": 200
                          },
                          "utm_campaign": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_campaign der Herkunft (Name der Werbekampagne)",
                            "maxLength": 200
                          },
                          "utm_content": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_content der Herkunft (Anzeige oder Link)",
                            "maxLength": 200
                          },
                          "utm_term": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "UTM-Parameter utm_term der Herkunft (Suchbegriff)",
                            "maxLength": 200
                          },
                          "last_activity_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der letzten Aktivität am Lead (ISO 8601, UTC), null ohne Aktivität",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "archived_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der Archivierung (ISO 8601, UTC), null bei aktiven Leads. GET /v1/leads zeigt archivierte nur mit include_archived",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Anlagezeitpunkt (ISO 8601, UTC)",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der letzten Änderung (ISO 8601, UTC)",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Heißeste Leads zuerst",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "campaign_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "company_id": null,
                          "salutation": "Herr",
                          "academic_title": null,
                          "first_name": "Max",
                          "last_name": "Mustermann",
                          "title": "Geschäftsführer",
                          "headline": "Geschäftsführer bei Beispiel GmbH",
                          "email": "max.mustermann@beispiel.de",
                          "email_status": null,
                          "phone": "+49 3012 3456",
                          "company": "Beispiel GmbH",
                          "website": "https://beispiel.de",
                          "employees": "11-50",
                          "street": null,
                          "postal_code": "10115",
                          "city": "Berlin",
                          "country": "DE",
                          "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                          "linkedin_network_distance": "DISTANCE_1",
                          "status": "interested",
                          "stage": "hot",
                          "outreach_status": "Ausstehend",
                          "score": 82,
                          "lead_source": "api",
                          "source_details": null,
                          "notes": null,
                          "assigned_user_id": null,
                          "show_in_crm": false,
                          "crm_only": false,
                          "is_priority": false,
                          "do_not_contact": false,
                          "meeting_scheduled_at": null,
                          "meeting_type": null,
                          "next_action": null,
                          "next_action_at": null,
                          "landing_page_url": "https://beispiel.dealsky.app/max-mustermann",
                          "personalized_video_url": null,
                          "personalized_video_thumbnail": null,
                          "landingpage_url_qrcode": null,
                          "utm_source": null,
                          "utm_medium": null,
                          "utm_campaign": null,
                          "utm_content": null,
                          "utm_term": null,
                          "last_activity_at": "2026-10-17T19:06:10.000Z",
                          "archived_at": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-17T19:06:10.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/leads/{id}/events": {
      "get": {
        "operationId": "listLeadEvents",
        "tags": [
          "Leads"
        ],
        "summary": "Ereignisse eines Leads",
        "description": "Was der Lead selbst getan hat oder was mit ihm passiert ist, neueste zuerst: Landingpage besucht (`pageview`), Video gestartet und angesehen, Buttons geklickt, Buchungsseite geöffnet, Termin bestätigt, Briefe übermittelt und versendet. Das sind die Ereignisse, die die App im Reiter „Journey“ neben dem Verlauf zeigt; den Verlauf (Nachrichten, Anrufe, Notizen) liefert GET /v1/leads/{id}/activities, beides gemischt GET /v1/leads/{id}/journey.\n\nSeitenaufrufe erkannter Bots und Link-Vorschauen werden nicht gespeichert. Ist das Tracking in den Einstellungen aus, entstehen keine Landingpage-Ereignisse.\n\nFilter: `type` und `channel` (je kommagetrennt), `from` (einschließlich) und `to` (ausschließlich) als Zeitpunkt.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Eine oder mehrere Arten, kommagetrennt, z. B. pageview,booking_confirmed",
              "items": {
                "type": "string",
                "enum": [
                  "pageview",
                  "video_start",
                  "video_progress",
                  "video_25",
                  "video_50",
                  "video_75",
                  "video_90",
                  "video_100",
                  "cta_clicked",
                  "middle_cta_clicked",
                  "final_cta_clicked",
                  "final_website_clicked",
                  "booking_page_opened",
                  "booking_confirmed",
                  "explainer_start",
                  "explainer_progress",
                  "explainer_cta_clicked",
                  "sent",
                  "delivered",
                  "opened",
                  "clicked",
                  "replied",
                  "bounced",
                  "unsubscribed",
                  "connection_sent",
                  "connection_accepted",
                  "message_sent",
                  "message_replied",
                  "inmail_sent",
                  "inmail_replied",
                  "follow",
                  "like",
                  "profile_view",
                  "linkedin_message_sent",
                  "linkedin_reply_received",
                  "linkedin_unknown",
                  "campaign_completed",
                  "tag_added",
                  "tag_removed",
                  "letter_planned",
                  "letter_production",
                  "letter_sent"
                ]
              }
            },
            "description": "Eine oder mehrere Arten, kommagetrennt, z. B. pageview,booking_confirmed",
            "style": "form",
            "explode": false
          },
          {
            "name": "channel",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Ein oder mehrere Kanäle, kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "email",
                  "linkedin",
                  "phone",
                  "letter",
                  "video",
                  "landingpage"
                ]
              }
            },
            "description": "Ein oder mehrere Kanäle, kommagetrennt",
            "style": "form",
            "explode": false
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Ereignisse ab diesem Zeitpunkt",
              "format": "date-time"
            },
            "description": "Nur Ereignisse ab diesem Zeitpunkt"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Ereignisse vor diesem Zeitpunkt",
              "format": "date-time"
            },
            "description": "Nur Ereignisse vor diesem Zeitpunkt"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Ereignisses",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string",
                            "description": "Art des Ereignisses, z. B. pageview (Landingpage besucht), video_progress, cta_clicked, booking_confirmed, letter_sent",
                            "enum": [
                              "pageview",
                              "video_start",
                              "video_progress",
                              "video_25",
                              "video_50",
                              "video_75",
                              "video_90",
                              "video_100",
                              "cta_clicked",
                              "middle_cta_clicked",
                              "final_cta_clicked",
                              "final_website_clicked",
                              "booking_page_opened",
                              "booking_confirmed",
                              "explainer_start",
                              "explainer_progress",
                              "explainer_cta_clicked",
                              "sent",
                              "delivered",
                              "opened",
                              "clicked",
                              "replied",
                              "bounced",
                              "unsubscribed",
                              "connection_sent",
                              "connection_accepted",
                              "message_sent",
                              "message_replied",
                              "inmail_sent",
                              "inmail_replied",
                              "follow",
                              "like",
                              "profile_view",
                              "linkedin_message_sent",
                              "linkedin_reply_received",
                              "linkedin_unknown",
                              "campaign_completed",
                              "tag_added",
                              "tag_removed",
                              "letter_planned",
                              "letter_production",
                              "letter_sent"
                            ]
                          },
                          "channel": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kanal: landingpage, linkedin, letter, email, phone, video",
                            "enum": [
                              "email",
                              "linkedin",
                              "phone",
                              "letter",
                              "video",
                              "landingpage",
                              null
                            ]
                          },
                          "occurred_at": {
                            "type": "string",
                            "description": "Zeitpunkt des Ereignisses",
                            "format": "date-time"
                          },
                          "campaign_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kampagne, falls bekannt",
                            "format": "uuid"
                          },
                          "subject": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kurztext zum Ereignis, falls vorhanden (in der App Spalte „Details“)"
                          },
                          "score_delta": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Punkte, die das Ereignis dem Lead-Score gegeben hat (in der Journey als +N)"
                          },
                          "video_progress_percent": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Nur bei video_progress und explainer_progress: wie weit das Video angesehen wurde (25, 50, 75 oder 100)"
                          },
                          "letter_pdf_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nur bei Brief-Ereignissen: Link zum PDF des Briefs"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Neueste Ereignisse",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "0e1f2a3b-4c5d-4e6f-8a7b-9c0d1e2f3a4b",
                          "type": "booking_confirmed",
                          "channel": "landingpage",
                          "occurred_at": "2026-10-17T19:06:10.000Z",
                          "campaign_id": null,
                          "subject": null,
                          "score_delta": 50,
                          "video_progress_percent": null,
                          "letter_pdf_url": null
                        },
                        {
                          "id": "1f2a3b4c-5d6e-4f7a-8b9c-0d1e2f3a4b5c",
                          "type": "video_progress",
                          "channel": "landingpage",
                          "occurred_at": "2026-10-17T19:04:55.000Z",
                          "campaign_id": null,
                          "subject": null,
                          "score_delta": 18,
                          "video_progress_percent": 75,
                          "letter_pdf_url": null
                        },
                        {
                          "id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
                          "type": "pageview",
                          "channel": "landingpage",
                          "occurred_at": "2026-10-17T19:02:31.000Z",
                          "campaign_id": null,
                          "subject": null,
                          "score_delta": 8,
                          "video_progress_percent": null,
                          "letter_pdf_url": null
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Nur Besuche und Buchungen im Oktober",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "0e1f2a3b-4c5d-4e6f-8a7b-9c0d1e2f3a4b",
                          "type": "booking_confirmed",
                          "channel": "landingpage",
                          "occurred_at": "2026-10-17T19:06:10.000Z",
                          "campaign_id": null,
                          "subject": null,
                          "score_delta": 50,
                          "video_progress_percent": null,
                          "letter_pdf_url": null
                        },
                        {
                          "id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
                          "type": "pageview",
                          "channel": "landingpage",
                          "occurred_at": "2026-10-17T19:02:31.000Z",
                          "campaign_id": null,
                          "subject": null,
                          "score_delta": 8,
                          "video_progress_percent": null,
                          "letter_pdf_url": null
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/leads/{id}/engagement": {
      "get": {
        "operationId": "getLeadEngagement",
        "tags": [
          "Leads"
        ],
        "summary": "Engagement eines Leads",
        "description": "Zusammenfassung wie im Lead-Panel: Score und Wärme (heiß, warm, kalt nach den Schwellen des Kontos, wie in der Leads-Tabelle), letzte Aktivität, Landingpage-Besuche, Video, Klicks, Buchungen und der LinkedIn-Stand (laufende Kampagne, Vernetzung, Antwort).\n\nAlle Zahlen sind exakt gezählt, auch bei mehr als 1000 Ereignissen. Gezählt werden alle Ereignisse des Leads, auch von früheren Landingpages.\n\nDer LinkedIn-Stand berücksichtigt nur Kampagnen auf LinkedIn-Konten, die die Person hinter dem Key in der App sehen darf.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "lead_id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "format": "uuid"
                        },
                        "score": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Lead-Score 0 bis 100"
                        },
                        "warmth": {
                          "type": "string",
                          "description": "Wärme wie in der Leads-Tabelle: hot ab thresholds.hot, warm ab thresholds.warm, sonst cold (ohne Score: cold)",
                          "enum": [
                            "hot",
                            "warm",
                            "cold"
                          ]
                        },
                        "thresholds": {
                          "type": "object",
                          "description": "Score-Grenzen für warmth aus den Einstellungen des Kontos",
                          "properties": {
                            "hot": {
                              "type": "number",
                              "description": "Ab diesem Score heiß (Einstellungen, Lead-Scoring; Standard 76)"
                            },
                            "warm": {
                              "type": "number",
                              "description": "Ab diesem Score warm (Standard 40)"
                            }
                          },
                          "additionalProperties": false
                        },
                        "last_activity_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte Aktivität laut Lead (Spalte „Letzte Aktivität“)",
                          "format": "date-time"
                        },
                        "last_event_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Jüngstes Ereignis (Landingpage, Video, Brief …)",
                          "format": "date-time"
                        },
                        "landing_page": {
                          "type": "object",
                          "description": "Zählung der Landingpage-Ereignisse des Leads",
                          "properties": {
                            "visits": {
                              "type": "integer",
                              "description": "Seitenaufrufe (in der App „Besucht (Nx)“)"
                            },
                            "first_visit_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Erster Seitenaufruf (Ereignis pageview), null ohne Besuch",
                              "format": "date-time"
                            },
                            "last_visit_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Letzter Seitenaufruf (Ereignis pageview), null ohne Besuch",
                              "format": "date-time"
                            },
                            "cta_clicks": {
                              "type": "integer",
                              "description": "Klicks auf die Buttons der Seite (Kopf, Mitte, Ende, Erklärvideo)"
                            },
                            "booking_page_opens": {
                              "type": "integer",
                              "description": "Buchungsseite geöffnet"
                            },
                            "bookings": {
                              "type": "integer",
                              "description": "Termine über die Seite bestätigt"
                            }
                          },
                          "additionalProperties": false
                        },
                        "video": {
                          "type": "object",
                          "description": "Stand des personalisierten Hauptvideos aus den Ereignissen video_start und video_progress",
                          "properties": {
                            "starts": {
                              "type": "integer",
                              "description": "Hauptvideo gestartet"
                            },
                            "max_progress_percent": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Höchster gemeldeter Fortschritt des Hauptvideos (25, 50, 75, 100), null ohne Meldung"
                            },
                            "completed": {
                              "type": "boolean",
                              "description": "Video bis zum Ende angesehen (Fortschritt 100)"
                            }
                          },
                          "additionalProperties": false
                        },
                        "meeting_scheduled_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Gesetzter Termin am Lead",
                          "format": "date-time"
                        },
                        "linkedin": {
                          "type": "object",
                          "description": "Nur Sequenzen auf LinkedIn-Konten, die der Key-Ersteller sehen darf",
                          "properties": {
                            "active_campaign": {
                              "type": [
                                "object",
                                "null"
                              ],
                              "description": "Kampagne, in der der Lead gerade läuft (im Lead-Panel „LinkedIn Kampagne“), sonst null",
                              "properties": {
                                "campaign_id": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "ID der laufenden Kampagne",
                                  "format": "uuid"
                                },
                                "campaign_name": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "null, wenn die Kampagne für den Key-Ersteller nicht sichtbar ist"
                                },
                                "sequence_status": {
                                  "type": "string",
                                  "description": "pending, active, in_progress oder waiting_for_connection"
                                }
                              },
                              "additionalProperties": false
                            },
                            "connection_status": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Vernetzung laut jüngster Sequenz: unknown, not_connected, pending, connected, withdrawn"
                            },
                            "connected_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zeitpunkt der Vernetzung laut jüngster Sequenz, null wenn nicht vernetzt",
                              "format": "date-time"
                            },
                            "replied": {
                              "type": "boolean",
                              "description": "Hat in einer LinkedIn-Kampagne geantwortet"
                            },
                            "replied_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zeitpunkt der Antwort (bei mehreren Kampagnen die jüngste)",
                              "format": "date-time"
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "score": 82,
                        "warmth": "hot",
                        "thresholds": {
                          "hot": 76,
                          "warm": 40
                        },
                        "last_activity_at": "2026-10-17T19:06:10.000Z",
                        "last_event_at": "2026-10-17T19:06:10.000Z",
                        "landing_page": {
                          "visits": 4,
                          "first_visit_at": "2026-10-15T08:31:12.000Z",
                          "last_visit_at": "2026-10-17T19:02:31.000Z",
                          "cta_clicks": 1,
                          "booking_page_opens": 1,
                          "bookings": 1
                        },
                        "video": {
                          "starts": 2,
                          "max_progress_percent": 75,
                          "completed": false
                        },
                        "meeting_scheduled_at": "2026-10-21T08:00:00.000Z",
                        "linkedin": {
                          "active_campaign": {
                            "campaign_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                            "campaign_name": "Geschäftsführer DACH Q4",
                            "sequence_status": "active"
                          },
                          "connection_status": "connected",
                          "connected_at": "2026-10-14T10:12:00.000Z",
                          "replied": false,
                          "replied_at": null
                        }
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/leads/{id}/journey": {
      "get": {
        "operationId": "listLeadJourney",
        "tags": [
          "Leads"
        ],
        "summary": "Zeitleiste eines Leads",
        "description": "Alles zu einem Lead in einer Liste, wie der Reiter „Journey“ im Lead-Panel: Verlauf (Nachrichten, Anrufe, Notizen, Kampagnen-Schritte, `source: activity`), Ereignisse (Landingpage, Video, Briefe, `source: event`) und als ältester Eintrag „Lead angelegt“ (`source: lead`).\n\nNeueste zuerst. Bei gleichem Zeitpunkt in derselben Reihenfolge wie die App: Aufnahme in die Kampagne, Aufnahme in die Sequenz, Sequenz gestoppt (Antwort, Termin, manuell), dann alles andere; Verlauf vor Ereignissen.\n\nSeitenweise über meta.next_cursor. Der Cursor merkt sich die Stelle des letzten Eintrags, darum gibt es beim Blättern keine Doppelten und keine Lücken.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Aktivität bzw. des Ereignisses; beim Eintrag lead_created die ID des Leads",
                            "format": "uuid"
                          },
                          "source": {
                            "type": "string",
                            "description": "activity (Verlauf, wie GET /v1/leads/{id}/activities), event (wie GET /v1/leads/{id}/events) oder lead (Lead angelegt)",
                            "enum": [
                              "activity",
                              "event",
                              "lead"
                            ]
                          },
                          "type": {
                            "type": "string",
                            "description": "Art, z. B. linkedin_message_sent, note, call_completed, pageview, booking_confirmed, lead_created"
                          },
                          "channel": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kanal, z. B. linkedin, email, phone, landingpage, letter, video; null wenn keiner zugeordnet ist (immer bei lead_created)"
                          },
                          "occurred_at": {
                            "type": "string",
                            "description": "Zeitpunkt des Eintrags (ISO 8601, UTC); bei Aktivitäten deren created_at, bei Ereignissen der Ereigniszeitpunkt",
                            "format": "date-time"
                          },
                          "campaign_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kampagne, aus der der Eintrag stammt, null ohne Kampagne",
                            "format": "uuid"
                          },
                          "subject": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Betreff der Aktivität bzw. Kurztext des Ereignisses, null wenn keiner vorhanden ist"
                          },
                          "content": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nur bei Aktivitäten: Text, z. B. einer Notiz oder Nachricht"
                          },
                          "metadata": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Nur bei Aktivitäten: Zusatzangaben wie bei GET /v1/leads/{id}/activities",
                            "additionalProperties": true
                          },
                          "score_delta": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Nur bei Ereignissen: Punkte für den Lead-Score"
                          },
                          "video_progress_percent": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Nur bei Video-Ereignissen mit Fortschritt"
                          },
                          "letter_pdf_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nur bei Brief-Ereignissen: Link zum PDF"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "0e1f2a3b-4c5d-4e6f-8a7b-9c0d1e2f3a4b",
                          "source": "event",
                          "type": "booking_confirmed",
                          "channel": "landingpage",
                          "occurred_at": "2026-10-17T19:06:10.000Z",
                          "campaign_id": null,
                          "subject": null,
                          "content": null,
                          "metadata": null,
                          "score_delta": 50,
                          "video_progress_percent": null,
                          "letter_pdf_url": null
                        },
                        {
                          "id": "9c7a1b2d-4e5f-4a6b-8c9d-0e1f2a3b4c5d",
                          "source": "activity",
                          "type": "linkedin_message_sent",
                          "channel": "linkedin",
                          "occurred_at": "2026-10-16T09:12:00.000Z",
                          "campaign_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "subject": null,
                          "content": "Hallo Herr Mustermann, danke fürs Vernetzen …",
                          "metadata": {},
                          "score_delta": null,
                          "video_progress_percent": null,
                          "letter_pdf_url": null
                        },
                        {
                          "id": "8b6a0c1d-3e4f-4a5b-9c8d-7e6f5a4b3c2d",
                          "source": "activity",
                          "type": "campaign_enrolled",
                          "channel": "linkedin",
                          "occurred_at": "2026-10-14T08:00:00.000Z",
                          "campaign_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "subject": null,
                          "content": "In Kampagne aufgenommen",
                          "metadata": {},
                          "score_delta": null,
                          "video_progress_percent": null,
                          "letter_pdf_url": null
                        },
                        {
                          "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "source": "lead",
                          "type": "lead_created",
                          "channel": null,
                          "occurred_at": "2026-10-01T08:00:00.000Z",
                          "campaign_id": null,
                          "subject": null,
                          "content": null,
                          "metadata": null,
                          "score_delta": null,
                          "video_progress_percent": null,
                          "letter_pdf_url": null
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/custom-fields": {
      "get": {
        "operationId": "listCustomFields",
        "tags": [
          "Leads"
        ],
        "summary": "Eigene Felder (Custom Fields) auflisten",
        "description": "Die Felder, die das Konto unter Einstellungen → Felder für Leads angelegt hat, in der Reihenfolge der App (Gruppe, dann Feld). Standardmäßig nur aktive Felder, wie die App sie im Lead-Panel zeigt; `include_inactive=true` liefert auch deaktivierte. Anlegen und Ändern von Feldern geht nur in der App (dort der Leitung vorbehalten).\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "include_inactive",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Auch deaktivierte Felder liefern (Standard: nein)"
            },
            "description": "Auch deaktivierte Felder liefern (Standard: nein)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c",
                            "field_key": "budget",
                            "field_name": "Budget",
                            "field_type": "currency",
                            "field_options": [],
                            "is_required": false,
                            "category_name": "Qualifizierung",
                            "default_value": null,
                            "is_active": true,
                            "display_statuses": [],
                            "created_at": "2026-09-01T08:00:00.000Z",
                            "updated_at": "2026-09-01T08:00:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Felddefinition",
                            "format": "uuid"
                          },
                          "field_key": {
                            "type": "string",
                            "description": "Schlüssel des Felds, so wird es in /v1/leads/{id}/custom-fields angesprochen"
                          },
                          "field_name": {
                            "type": "string",
                            "description": "Anzeigename in der App"
                          },
                          "field_type": {
                            "type": "string",
                            "description": "Typ, bestimmt das erlaubte Format des Werts (siehe PUT /v1/leads/{id}/custom-fields)",
                            "enum": [
                              "text",
                              "textarea",
                              "number",
                              "decimal",
                              "currency",
                              "date",
                              "select",
                              "multiselect",
                              "checkbox",
                              "user",
                              "url",
                              "email",
                              "phone"
                            ]
                          },
                          "field_options": {
                            "type": "array",
                            "description": "Erlaubte Werte bei select und multiselect, sonst leer",
                            "items": {
                              "type": "string"
                            }
                          },
                          "is_required": {
                            "type": "boolean",
                            "description": "In der App als Pflichtfeld markiert (Stern). Die App erzwingt es beim Speichern nicht, die API auch nicht."
                          },
                          "category_name": {
                            "type": "string",
                            "description": "Gruppe, unter der das Feld in der App steht"
                          },
                          "default_value": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Gespeicherter Standardwert der Definition. Die App legt Felder mit null an und setzt ihn nicht in Leads ein; meist null"
                          },
                          "is_active": {
                            "type": "boolean",
                            "description": "Nur aktive Felder zeigt die App an, nur sie lassen sich setzen"
                          },
                          "display_statuses": {
                            "type": "array",
                            "description": "Die App zeigt das Feld im Lead-Panel nur bei Leads mit diesen Status; leer = immer. Lesen und Setzen per API gehen unabhängig davon.",
                            "items": {
                              "type": "string"
                            }
                          },
                          "created_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Angelegt am",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zuletzt geändert am",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "2b3c4d5e-6f70-4a81-9b2c-3d4e5f6a7b8c",
                          "field_key": "budget",
                          "field_name": "Budget",
                          "field_type": "currency",
                          "field_options": [],
                          "is_required": false,
                          "category_name": "Qualifizierung",
                          "default_value": null,
                          "is_active": true,
                          "display_statuses": [],
                          "created_at": "2026-09-01T08:00:00.000Z",
                          "updated_at": "2026-09-01T08:00:00.000Z"
                        },
                        {
                          "id": "3c4d5e6f-7081-4b92-8c3d-4e5f6a7b8c9d",
                          "field_key": "interesse",
                          "field_name": "Interesse an",
                          "field_type": "multiselect",
                          "field_options": [
                            "Video",
                            "Landingpage",
                            "Brief"
                          ],
                          "is_required": false,
                          "category_name": "Qualifizierung",
                          "default_value": null,
                          "is_active": true,
                          "display_statuses": [],
                          "created_at": "2026-09-01T08:00:00.000Z",
                          "updated_at": "2026-09-01T08:00:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/leads/{id}/custom-fields": {
      "get": {
        "operationId": "getLeadCustomFields",
        "tags": [
          "Leads"
        ],
        "summary": "Werte der eigenen Felder eines Leads",
        "description": "Ein Objekt mit dem Schlüssel jedes aktiven Felds und dem Wert beim Lead, `null` = kein Wert. Werte kommen als Text, so wie die App sie speichert, Mehrfachauswahl als Liste. Formate je Typ stehen bei PUT /v1/leads/{id}/custom-fields. Werte deaktivierter Felder zeigt die App nicht, die API auch nicht.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "description": "Feld-Schlüssel → Wert (Text, Liste bei multiselect, null = leer)",
                      "examples": [
                        {
                          "budget": "15000",
                          "entscheider": "true",
                          "interesse": [
                            "Video",
                            "Landingpage"
                          ],
                          "naechster_termin": "2026-11-03",
                          "zustaendig": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                          "bemerkung": null
                        }
                      ],
                      "additionalProperties": true
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "budget": "15000",
                        "entscheider": "true",
                        "interesse": [
                          "Video",
                          "Landingpage"
                        ],
                        "naechster_termin": "2026-11-03",
                        "zustaendig": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                        "bemerkung": null
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read"
      },
      "put": {
        "operationId": "setLeadCustomFields",
        "tags": [
          "Leads"
        ],
        "summary": "Werte der eigenen Felder eines Leads setzen",
        "description": "Setzt die übergebenen Felder, alle anderen bleiben unverändert. `null`, leerer Text oder eine leere Liste leeren ein Feld. Schlüssel aus GET /v1/custom-fields; unbekannte oder deaktivierte Felder und Werte im falschen Format ergeben 400 mit allen Fehlern in `error.details`, dann wird nichts geschrieben. Die Antwort ist der Stand danach wie bei GET.\n\nGespeichert wird wie im Lead-Panel der App: ein Wert je Lead und Feld, als Text. Kein Eintrag im Verlauf, keine weitere Wirkung. Pflichtfelder erzwingt die App beim Speichern nicht, die API auch nicht. Ob die App ein Feld nur bei bestimmten Status zeigt (`display_statuses`), spielt fürs Setzen keine Rolle.\n\n| Typ | Wert beim Setzen | gespeichert und gelesen als |\n|---|---|---|\n| text, textarea | Text, höchstens 10.000 Zeichen | Text |\n| number | ganze Zahl, z. B. `42` oder `\"42\"` | `\"42\"` |\n| decimal | Zahl, Punkt als Trenner, z. B. `12.5` | `\"12.5\"` |\n| currency | Betrag in Euro, höchstens zwei Nachkommastellen, z. B. `1500.5` oder `\"1500.50\"` | `\"1500.5\"` bzw. `\"1500.50\"` |\n| date | `JJJJ-MM-TT`, gültiges Kalenderdatum | `\"2026-11-03\"` |\n| select | genau eine der `field_options` | Text |\n| multiselect | Liste aus `field_options`, z. B. `[\"A\", \"B\"]` | Liste |\n| checkbox | `true`, `false` oder `\"unclear\"` (wie Ja, Nein, Unklar in der Qualifizierung) | `\"true\"`, `\"false\"`, `\"unclear\"` |\n| user | ID eines Team-Mitglieds (GET /v1/team) | ID |\n| url | vollständige URL mit http:// oder https:// | Text |\n| email | E-Mail-Adresse (wird klein geschrieben) | Text |\n| phone | Telefonnummer aus Ziffern, Leerzeichen, + ( ) / . - | Text wie übergeben |\n\nHöchstens 200 Felder je Aufruf. Mit Test-Key kommt dieselbe Prüfung und die Liste der Änderungen, geschrieben wird nichts.\n\n**Berechtigung:** `write:leads`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Feld-Schlüssel → Wert. Format je Typ siehe Tabelle.",
                "additionalProperties": true
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "budget": 15000,
                    "entscheider": true,
                    "interesse": [
                      "Video",
                      "Landingpage"
                    ],
                    "naechster_termin": "2026-11-03",
                    "bemerkung": null
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "description": "Alle aktiven Felder mit Wert nach dem Speichern, wie GET",
                      "additionalProperties": true
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "budget": "15000",
                        "entscheider": "true",
                        "interesse": [
                          "Video",
                          "Landingpage"
                        ],
                        "naechster_termin": "2026-11-03",
                        "zustaendig": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                        "bemerkung": null
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:leads",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/lists": {
      "get": {
        "operationId": "listLists",
        "tags": [
          "Listen"
        ],
        "summary": "Listen auflisten",
        "description": "Neueste zuerst. `name` sucht als Teilstring (Groß/Klein egal).\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Teil des Namens (Groß/Klein egal)",
              "maxLength": 200
            },
            "description": "Teil des Namens (Groß/Klein egal)"
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Listen, die an diese Kampagne gebunden sind",
              "format": "uuid"
            },
            "description": "Nur Listen, die an diese Kampagne gebunden sind"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                            "name": "Messe Köln 2026",
                            "description": "Kontakte vom Messestand",
                            "campaign_id": null,
                            "folder_id": null,
                            "leads_count": 128,
                            "personalized_landing_pages_count": 0,
                            "personalized_videos_count": 0,
                            "created_at": "2026-10-01T08:00:00.000Z",
                            "updated_at": "2026-10-18T09:12:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Liste",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name der Liste, wie er in der App steht",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Freitext zur Liste, z. B. woher die Kontakte stammen. null leert sie",
                            "maxLength": 2000
                          },
                          "campaign_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kampagne, an die die Liste gebunden ist",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "folder_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Ordner der Liste (siehe /v1/list-folders), null = oberste Ebene",
                            "format": "uuid"
                          },
                          "leads_count": {
                            "type": "integer",
                            "description": "Leads in der Liste ohne archivierte, von der Datenbank mitgezählt",
                            "readOnly": true
                          },
                          "personalized_landing_pages_count": {
                            "type": "integer",
                            "description": "Leads der Liste (ohne archivierte) mit personalisierter Landingpage",
                            "readOnly": true
                          },
                          "personalized_videos_count": {
                            "type": "integer",
                            "description": "Leads der Liste (ohne archivierte) mit personalisiertem Video",
                            "readOnly": true
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt der Anlage",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "Zeitpunkt der letzten Änderung, auch wenn sich die Lead-Zahlen geändert haben",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "name": "Messe Köln 2026",
                          "description": "Kontakte vom Messestand",
                          "campaign_id": null,
                          "folder_id": null,
                          "leads_count": 128,
                          "personalized_landing_pages_count": 0,
                          "personalized_videos_count": 0,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      },
      "post": {
        "operationId": "createList",
        "tags": [
          "Listen"
        ],
        "summary": "Liste anlegen",
        "description": "Legt eine leere Liste an. Ohne `folder_id` steht sie auf der obersten Ebene. Mit `folder_id` (siehe GET /v1/list-folders) entsteht sie direkt in diesem Ordner, wie „Neue Liste“ in einem geöffneten Ordner der App; ein unbekannter oder fremder Ordner ergibt 400. Für `folder_id` braucht es einen API-Key, der einer Person zugeordnet ist; ohne Ordner legen auch ältere Keys ohne Person Listen an. Leads kommen danach mit `list_id` über `POST /v1/leads` oder `POST /v1/leads/bulk` hinein. Kostet keine Credits. Mit Test-Key wird geprüft, aber nichts angelegt (`would_create`).\n\n**Berechtigung:** `write:leads`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name der Liste, wie er in der App steht",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Freitext zur Liste, z. B. woher die Kontakte stammen. null leert sie",
                    "maxLength": 2000
                  },
                  "folder_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Ordner, in dem die Liste entsteht (siehe GET /v1/list-folders). Weglassen oder null = oberste Ebene",
                    "format": "uuid"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "name": "Messe Köln 2026",
                    "description": "Kontakte vom Messestand"
                  }
                },
                "beispiel2": {
                  "summary": "Direkt in einem Ordner anlegen",
                  "value": {
                    "name": "Messe Köln 2026",
                    "folder_id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "name": "Messe Köln 2026",
                          "description": "Kontakte vom Messestand",
                          "campaign_id": null,
                          "folder_id": null,
                          "leads_count": 128,
                          "personalized_landing_pages_count": 0,
                          "personalized_videos_count": 0,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Liste",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Liste, wie er in der App steht",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext zur Liste, z. B. woher die Kontakte stammen. null leert sie",
                          "maxLength": 2000
                        },
                        "campaign_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kampagne, an die die Liste gebunden ist",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "folder_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ordner der Liste (siehe /v1/list-folders), null = oberste Ebene",
                          "format": "uuid"
                        },
                        "leads_count": {
                          "type": "integer",
                          "description": "Leads in der Liste ohne archivierte, von der Datenbank mitgezählt",
                          "readOnly": true
                        },
                        "personalized_landing_pages_count": {
                          "type": "integer",
                          "description": "Leads der Liste (ohne archivierte) mit personalisierter Landingpage",
                          "readOnly": true
                        },
                        "personalized_videos_count": {
                          "type": "integer",
                          "description": "Leads der Liste (ohne archivierte) mit personalisiertem Video",
                          "readOnly": true
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zeitpunkt der letzten Änderung, auch wenn sich die Lead-Zahlen geändert haben",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "name": "Messe Köln 2026",
                        "description": "Kontakte vom Messestand",
                        "campaign_id": null,
                        "folder_id": null,
                        "leads_count": 128,
                        "personalized_landing_pages_count": 0,
                        "personalized_videos_count": 0,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Direkt in einem Ordner anlegen",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "name": "Messe Köln 2026",
                        "description": null,
                        "campaign_id": null,
                        "folder_id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                        "leads_count": 0,
                        "personalized_landing_pages_count": 0,
                        "personalized_videos_count": 0,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-01T08:00:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:leads",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/lists/{id}": {
      "get": {
        "operationId": "getList",
        "tags": [
          "Listen"
        ],
        "summary": "Eine Liste abrufen",
        "description": "Liefert eine Liste des eigenen Kontos mit Ordner (`folder_id`), gebundener Kampagne (`campaign_id`) und den Zählern der App für Leads, persönliche Landingpages und Videos. Die Leads selbst liefert `GET /v1/leads?list_id=…`. Eine unbekannte oder fremde ID ergibt 404.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Liste",
              "format": "uuid"
            },
            "description": "ID der Liste"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "name": "Messe Köln 2026",
                          "description": "Kontakte vom Messestand",
                          "campaign_id": null,
                          "folder_id": null,
                          "leads_count": 128,
                          "personalized_landing_pages_count": 0,
                          "personalized_videos_count": 0,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Liste",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Liste, wie er in der App steht",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext zur Liste, z. B. woher die Kontakte stammen. null leert sie",
                          "maxLength": 2000
                        },
                        "campaign_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kampagne, an die die Liste gebunden ist",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "folder_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ordner der Liste (siehe /v1/list-folders), null = oberste Ebene",
                          "format": "uuid"
                        },
                        "leads_count": {
                          "type": "integer",
                          "description": "Leads in der Liste ohne archivierte, von der Datenbank mitgezählt",
                          "readOnly": true
                        },
                        "personalized_landing_pages_count": {
                          "type": "integer",
                          "description": "Leads der Liste (ohne archivierte) mit personalisierter Landingpage",
                          "readOnly": true
                        },
                        "personalized_videos_count": {
                          "type": "integer",
                          "description": "Leads der Liste (ohne archivierte) mit personalisiertem Video",
                          "readOnly": true
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zeitpunkt der letzten Änderung, auch wenn sich die Lead-Zahlen geändert haben",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "name": "Messe Köln 2026",
                        "description": "Kontakte vom Messestand",
                        "campaign_id": null,
                        "folder_id": null,
                        "leads_count": 128,
                        "personalized_landing_pages_count": 0,
                        "personalized_videos_count": 0,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read"
      },
      "patch": {
        "operationId": "updateList",
        "tags": [
          "Listen"
        ],
        "summary": "Liste umbenennen, Beschreibung ändern oder in einen Ordner verschieben",
        "description": "Nur übergebene Felder werden geändert. `folder_id` verschiebt die Liste in einen Ordner (siehe GET /v1/list-folders), `null` holt sie auf die oberste Ebene, wie das Verschieben in der App. Leads, Kampagne und Landingpages der Liste bleiben unberührt. Zum Verschieben braucht es einen API-Key, der einer Person zugeordnet ist; Name und Beschreibung ändern auch ältere Keys ohne Person.\n\n**Berechtigung:** `write:leads`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Liste",
              "format": "uuid"
            },
            "description": "ID der Liste"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name der Liste, wie er in der App steht",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Freitext zur Liste, z. B. woher die Kontakte stammen. null leert sie",
                    "maxLength": 2000
                  },
                  "folder_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Ordner der Liste (siehe /v1/list-folders), null = oberste Ebene",
                    "format": "uuid"
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "name": "Messe Köln 2026 (nachbearbeitet)"
                  }
                },
                "beispiel2": {
                  "summary": "In einen Ordner verschieben",
                  "value": {
                    "folder_id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "name": "Messe Köln 2026",
                          "description": "Kontakte vom Messestand",
                          "campaign_id": null,
                          "folder_id": null,
                          "leads_count": 128,
                          "personalized_landing_pages_count": 0,
                          "personalized_videos_count": 0,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Liste",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Liste, wie er in der App steht",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext zur Liste, z. B. woher die Kontakte stammen. null leert sie",
                          "maxLength": 2000
                        },
                        "campaign_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kampagne, an die die Liste gebunden ist",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "folder_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ordner der Liste (siehe /v1/list-folders), null = oberste Ebene",
                          "format": "uuid"
                        },
                        "leads_count": {
                          "type": "integer",
                          "description": "Leads in der Liste ohne archivierte, von der Datenbank mitgezählt",
                          "readOnly": true
                        },
                        "personalized_landing_pages_count": {
                          "type": "integer",
                          "description": "Leads der Liste (ohne archivierte) mit personalisierter Landingpage",
                          "readOnly": true
                        },
                        "personalized_videos_count": {
                          "type": "integer",
                          "description": "Leads der Liste (ohne archivierte) mit personalisiertem Video",
                          "readOnly": true
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zeitpunkt der letzten Änderung, auch wenn sich die Lead-Zahlen geändert haben",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "name": "Messe Köln 2026 (nachbearbeitet)",
                        "description": "Kontakte vom Messestand",
                        "campaign_id": null,
                        "folder_id": null,
                        "leads_count": 128,
                        "personalized_landing_pages_count": 0,
                        "personalized_videos_count": 0,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "In einen Ordner verschieben",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "name": "Messe Köln 2026",
                        "description": "Kontakte vom Messestand",
                        "campaign_id": null,
                        "folder_id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                        "leads_count": 128,
                        "personalized_landing_pages_count": 0,
                        "personalized_videos_count": 0,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:leads",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/list-folders": {
      "get": {
        "operationId": "listListFolders",
        "tags": [
          "Listen"
        ],
        "summary": "Ordner für Listen auflisten",
        "description": "Alle Ordner des Kontos, nach Name sortiert wie in der App. Unterordner haben `parent_folder_id`. Welche Listen in einem Ordner liegen, steht in `folder_id` der Listen (GET /v1/lists).\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                            "name": "Messen 2026",
                            "parent_folder_id": null,
                            "created_at": "2026-10-01T08:00:00.000Z",
                            "updated_at": "2026-10-01T08:00:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Ordners",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name des Ordners",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "parent_folder_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Übergeordneter Ordner, null = oberste Ebene. Wie in der App höchstens zwei Ebenen: der übergeordnete Ordner muss selbst auf oberster Ebene liegen.",
                            "format": "uuid"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Angelegt am",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "Zuletzt geändert am (auch beim Umbenennen oder Verschieben)",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "7e6d5c4b-3a2f-4e1d-8c9b-8a7f6e5d4c3b",
                          "name": "Köln",
                          "parent_folder_id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-01T08:00:00.000Z"
                        },
                        {
                          "id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                          "name": "Messen 2026",
                          "parent_folder_id": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-01T08:00:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      },
      "post": {
        "operationId": "createListFolder",
        "tags": [
          "Listen"
        ],
        "summary": "Ordner anlegen",
        "description": "Legt einen Ordner auf oberster Ebene oder, mit `parent_folder_id`, als Unterordner an. Wie in der App höchstens zwei Ebenen. Ein gleichnamiger Unterordner im selben Ordner ergibt 409. Listen kommen per PATCH /v1/lists/{id} mit `folder_id` hinein.\n\n**Berechtigung:** `write:leads`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name des Ordners",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "parent_folder_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Übergeordneter Ordner, null = oberste Ebene. Wie in der App höchstens zwei Ebenen: der übergeordnete Ordner muss selbst auf oberster Ebene liegen.",
                    "format": "uuid"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "name": "Messen 2026"
                  }
                },
                "beispiel2": {
                  "summary": "Unterordner",
                  "value": {
                    "name": "Köln",
                    "parent_folder_id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                          "name": "Messen 2026",
                          "parent_folder_id": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-01T08:00:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Ordners",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name des Ordners",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "parent_folder_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Übergeordneter Ordner, null = oberste Ebene. Wie in der App höchstens zwei Ebenen: der übergeordnete Ordner muss selbst auf oberster Ebene liegen.",
                          "format": "uuid"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Angelegt am",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zuletzt geändert am (auch beim Umbenennen oder Verschieben)",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                        "name": "Messen 2026",
                        "parent_folder_id": null,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-01T08:00:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Unterordner",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "7e6d5c4b-3a2f-4e1d-8c9b-8a7f6e5d4c3b",
                        "name": "Köln",
                        "parent_folder_id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-01T08:00:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:leads",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/list-folders/{id}": {
      "patch": {
        "operationId": "updateListFolder",
        "tags": [
          "Listen"
        ],
        "summary": "Ordner umbenennen",
        "description": "Ändert den Namen, wie „Umbenennen“ in der App. Verschieben von Ordnern bietet die App nicht an, die API darum auch nicht. Ein gleichnamiger Unterordner im selben Ordner ergibt 409.\n\n**Berechtigung:** `write:leads`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Ordners",
              "format": "uuid"
            },
            "description": "ID des Ordners"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name des Ordners",
                    "minLength": 1,
                    "maxLength": 200
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "name": "Messen 2027"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                          "name": "Messen 2026",
                          "parent_folder_id": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-01T08:00:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Ordners",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name des Ordners",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "parent_folder_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Übergeordneter Ordner, null = oberste Ebene. Wie in der App höchstens zwei Ebenen: der übergeordnete Ordner muss selbst auf oberster Ebene liegen.",
                          "format": "uuid"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Angelegt am",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zuletzt geändert am (auch beim Umbenennen oder Verschieben)",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                        "name": "Messen 2027",
                        "parent_folder_id": null,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:leads",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      },
      "delete": {
        "operationId": "deleteListFolder",
        "tags": [
          "Listen"
        ],
        "summary": "Ordner löschen (Listen bleiben erhalten)",
        "description": "Löscht nur den Ordner, wie in der App: Listen darin und Unterordner (samt ihren Listen) bleiben erhalten und rücken auf die oberste Ebene. Leads, Kampagnen und Landingpages sind nicht betroffen. Die Antwort nennt, wie viele Listen und Unterordner verschoben wurden. Listen selbst löschen geht hierüber nicht.\n\n**Berechtigung:** `write:leads`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Ordners",
              "format": "uuid"
            },
            "description": "ID des Ordners"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "Immer true, wenn der Ordner gelöscht wurde"
                        },
                        "id": {
                          "type": "string",
                          "description": "ID des gelöschten Ordners",
                          "format": "uuid"
                        },
                        "lists_moved_to_top": {
                          "type": "integer",
                          "description": "Listen, die im Ordner lagen und jetzt auf oberster Ebene stehen"
                        },
                        "subfolders_moved_to_top": {
                          "type": "integer",
                          "description": "Unterordner, die jetzt auf oberster Ebene stehen (ihre Listen bleiben darin)"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "deleted": true,
                        "id": "6d5c4b3a-2f1e-4d0c-9b8a-7f6e5d4c3b2a",
                        "lists_moved_to_top": 3,
                        "subfolders_moved_to_top": 1
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:leads",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/exclusions": {
      "get": {
        "operationId": "listExclusions",
        "tags": [
          "Ausschlüsse"
        ],
        "summary": "Ausschlüsse auflisten",
        "description": "Einträge der Blacklist, neueste zuerst. `type` filtert nach Art (auch die älteren Arten linkedin und linkedin_company), `value` sucht als Teilstring im gespeicherten, normalisierten Wert (Groß/Klein egal).\n\n**Berechtigung:** `read:exclusions`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Einträge dieser Art",
              "enum": [
                "email",
                "domain",
                "linkedin_profile",
                "linkedin",
                "linkedin_member_id",
                "linkedin_company",
                "company_name"
              ]
            },
            "description": "Nur Einträge dieser Art"
          },
          {
            "name": "value",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Teilstring-Suche im Wert",
              "maxLength": 500
            },
            "description": "Teilstring-Suche im Wert"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
                            "type": "domain",
                            "value": "wettbewerber.de",
                            "reason": "Wettbewerber",
                            "created_at": "2026-10-18T09:12:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Ausschlusses",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string",
                            "description": "email, domain (E-Mail- oder Website-Domain), linkedin_profile (Profil-URL), linkedin_member_id, company_name (exakter Firmenname). Nur lesbar (ältere Einträge): linkedin (wie linkedin_profile), linkedin_company (Firmen-URL)",
                            "enum": [
                              "email",
                              "domain",
                              "linkedin_profile",
                              "linkedin",
                              "linkedin_member_id",
                              "linkedin_company",
                              "company_name"
                            ]
                          },
                          "value": {
                            "type": "string",
                            "description": "Wird normalisiert: E-Mail und Member-ID klein, Domain ohne https:// und www. Ein LinkedIn-Profil bleibt, wie es übergeben wurde (ohne Leerzeichen am Rand).",
                            "minLength": 1,
                            "maxLength": 500
                          },
                          "reason": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Freitext, warum der Eintrag auf der Liste steht, z. B. Wettbewerber",
                            "maxLength": 500
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Angelegt am",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
                          "type": "domain",
                          "value": "wettbewerber.de",
                          "reason": "Wettbewerber",
                          "created_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:exclusions",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      },
      "post": {
        "operationId": "createExclusion",
        "tags": [
          "Ausschlüsse"
        ],
        "summary": "Ausschluss anlegen",
        "description": "Ab sofort wird niemand mehr kontaktiert, auf den der Ausschluss passt. Bereits laufende Leads, die passen, werden wie in der App aus aktiven Kampagnen genommen. Gibt es den Eintrag schon, kommt 409 mit `error.details.existing_id`.\n\nEin LinkedIn-Profil gilt als vorhanden, wenn dasselbe Profil schon als `linkedin_profile` oder als älterer Eintrag `linkedin` auf der Liste steht, in welcher Schreibweise auch immer (mit oder ohne www, Länder-Subdomain, Groß/Klein, Parameter, Unterseiten, Schrägstrich am Ende). So liest auch der Abgleich der Kampagnen die Liste. Eine Member-ID gilt ohne Groß/Klein als vorhanden.\n\n**Berechtigung:** `write:exclusions`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "description": "email, domain (E-Mail- oder Website-Domain), linkedin_profile (Profil-URL), linkedin_member_id, company_name (exakter Firmenname)",
                    "enum": [
                      "email",
                      "domain",
                      "linkedin_profile",
                      "linkedin_member_id",
                      "company_name"
                    ]
                  },
                  "value": {
                    "type": "string",
                    "description": "Wird normalisiert: E-Mail und Member-ID klein, Domain ohne https:// und www. Ein LinkedIn-Profil bleibt, wie es übergeben wurde (ohne Leerzeichen am Rand).",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "reason": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Freitext, warum der Eintrag auf der Liste steht, z. B. Wettbewerber",
                    "maxLength": 500
                  }
                },
                "required": [
                  "type",
                  "value"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "type": "domain",
                    "value": "https://www.wettbewerber.de",
                    "reason": "Wettbewerber"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
                          "type": "domain",
                          "value": "wettbewerber.de",
                          "reason": "Wettbewerber",
                          "created_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Ausschlusses",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "type": {
                          "type": "string",
                          "description": "email, domain (E-Mail- oder Website-Domain), linkedin_profile (Profil-URL), linkedin_member_id, company_name (exakter Firmenname). Nur lesbar (ältere Einträge): linkedin (wie linkedin_profile), linkedin_company (Firmen-URL)",
                          "enum": [
                            "email",
                            "domain",
                            "linkedin_profile",
                            "linkedin",
                            "linkedin_member_id",
                            "linkedin_company",
                            "company_name"
                          ]
                        },
                        "value": {
                          "type": "string",
                          "description": "Wird normalisiert: E-Mail und Member-ID klein, Domain ohne https:// und www. Ein LinkedIn-Profil bleibt, wie es übergeben wurde (ohne Leerzeichen am Rand).",
                          "minLength": 1,
                          "maxLength": 500
                        },
                        "reason": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Freitext, warum der Eintrag auf der Liste steht, z. B. Wettbewerber",
                          "maxLength": 500
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Angelegt am",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d",
                        "type": "domain",
                        "value": "wettbewerber.de",
                        "reason": "Wettbewerber",
                        "created_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:exclusions",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/exclusions/{id}": {
      "delete": {
        "operationId": "deleteExclusion",
        "tags": [
          "Ausschlüsse"
        ],
        "summary": "Ausschluss entfernen",
        "description": "Bereits gestoppte Leads laufen dadurch nicht automatisch wieder an.\n\n**Berechtigung:** `write:exclusions`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es; ältere Keys ohne zugeordnete Person bleiben hier gültig)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Ausschlusses",
              "format": "uuid"
            },
            "description": "ID des Ausschlusses"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "Immer true, wenn der Ausschluss entfernt wurde"
                        },
                        "id": {
                          "type": "string",
                          "description": "ID des entfernten Ausschlusses",
                          "format": "uuid"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "deleted": true,
                        "id": "2a3b4c5d-6e7f-4a8b-9c0d-1e2f3a4b5c6d"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:exclusions",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/lead-scout/searches": {
      "get": {
        "operationId": "listLeadScoutSearches",
        "tags": [
          "Lead Scout"
        ],
        "summary": "Bisherige Lead-Scout-Suchen auflisten",
        "description": "Alle Google-Suchen des Kontos, neueste zuerst, mit Suchparametern und der Zahl gefundener Leads. `leads_found` zählt wie die Ergebnisliste der App: fertig ausgewertet, von der KI nicht als unpassend markiert, mit Firma, Entscheider und E-Mail (dazu Telefon oder Adresse, falls gefordert), höchstens so viele wie gewünscht. Anders als die Startseite der App, die nur die letzten offenen und fertigen Suchen zeigt, kommen hier auch fehlgeschlagene. Mehrere Filter werden mit UND verknüpft.\n\nDie Suchen entstehen in der App unter Lead Scout > Google-Suche (oder im Assistenten). Über die API lassen sie sich nur lesen: Starten kostet Websuche ohne Credits und Speichern kostet 2 Credits je Lead, beides bleibt in der App. Abfragen kostet nichts.\n\nJedes Mitglied mit dem Recht für den Lead Scout sieht alle Suchen des Kontos, wie in der App. Suchen, die in der App entfernt wurden, fehlen.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `outreach.lead_scout.search` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Ein oder mehrere Status, kommagetrennt, z. B. queued,running für alles, was noch läuft",
              "items": {
                "type": "string",
                "enum": [
                  "queued",
                  "running",
                  "succeeded",
                  "failed"
                ]
              }
            },
            "description": "Ein oder mehrere Status, kommagetrennt, z. B. queued,running für alles, was noch läuft",
            "style": "form",
            "explode": false
          },
          {
            "name": "list_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Suchen mit dieser Zielliste",
              "format": "uuid"
            },
            "description": "Nur Suchen mit dieser Zielliste"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Suchen, die seitdem gestartet wurden",
              "format": "date-time"
            },
            "description": "Nur Suchen, die seitdem gestartet wurden"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "7d3e9b21-4c5a-4f6e-8a1b-2c3d4e5f6a7b",
                            "kind": "web",
                            "status": "succeeded",
                            "query": "Pflegedienst",
                            "filters": {
                              "location": "Hamburg",
                              "industry": "Gesundheitswesen",
                              "country": "de",
                              "language": "de",
                              "time_range": null,
                              "company_websites_only": true,
                              "exclude_existing_leads": true,
                              "single_decision_maker_only": true,
                              "required_data": [
                                "phone"
                              ],
                              "domain_keywords": [
                                "pflege"
                              ],
                              "exclude_keywords": "Stellenangebot",
                              "target_audience": "Ambulante Pflegedienste mit 10 bis 50 Mitarbeitenden"
                            },
                            "leads_requested": 20,
                            "leads_found": 14,
                            "message": "Es wurden nur 14 von 20 gewünschten Leads gefunden. Mögliche Gründe: strenge Filter (z. B. „Nur Unternehmenswebsites“, Pflicht-Telefon oder Pflicht-Adresse) oder ein kleiner lokaler Markt.",
                            "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                            "created_by": null,
                            "created_at": "2026-10-17T09:30:12.418Z",
                            "updated_at": "2026-10-17T09:41:55.902Z",
                            "finished_at": "2026-10-17T09:41:55.902Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Suche",
                            "format": "uuid"
                          },
                          "kind": {
                            "type": "string",
                            "description": "Art der Suche: web ist die Google-Suche mit Auswertung der Firmenwebsites (in der App „Google-Suche“)",
                            "enum": [
                              "web"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "description": "queued wartet, running sucht und wertet Websites aus, succeeded ist fertig, failed ist gescheitert",
                            "enum": [
                              "queued",
                              "running",
                              "succeeded",
                              "failed"
                            ]
                          },
                          "query": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Suchbegriff"
                          },
                          "filters": {
                            "type": "object",
                            "description": "Suchparameter in Kurzform",
                            "properties": {
                              "location": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Ort der Suche"
                              },
                              "industry": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Branche, null ohne Einschränkung"
                              },
                              "country": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Land der Google-Suche, z. B. de"
                              },
                              "language": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Sprache der Google-Suche, z. B. de"
                              },
                              "time_range": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Nur Seiten aus diesem Zeitraum (hour, day, week, month, year), null für alle Zeiten",
                                "enum": [
                                  "hour",
                                  "day",
                                  "week",
                                  "month",
                                  "year",
                                  null
                                ]
                              },
                              "company_websites_only": {
                                "type": "boolean",
                                "description": "Nur Unternehmenswebsites (mit Impressum), keine Verzeichnisse und Portale"
                              },
                              "exclude_existing_leads": {
                                "type": "boolean",
                                "description": "Firmen, die schon als Lead im Konto stehen, wurden übersprungen"
                              },
                              "single_decision_maker_only": {
                                "type": "boolean",
                                "description": "Nur ein Entscheider je Firma"
                              },
                              "required_data": {
                                "type": "array",
                                "description": "Zusätzlich verlangte Angaben: address (vollständige Adresse für Briefe), phone (Telefon). Firma, Entscheider und E-Mail sind immer Pflicht",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "address",
                                    "phone"
                                  ]
                                }
                              },
                              "domain_keywords": {
                                "type": "array",
                                "description": "Begriffe, die in der Domain vorkommen müssen",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "exclude_keywords": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Ausgeschlossene Begriffe"
                              },
                              "target_audience": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Beschreibung der Zielgruppe, gegen die die KI die Treffer geprüft hat"
                              }
                            },
                            "additionalProperties": false
                          },
                          "leads_requested": {
                            "type": "integer",
                            "description": "Gewünschte Anzahl Leads",
                            "minimum": 1
                          },
                          "leads_found": {
                            "type": "integer",
                            "description": "Gefundene Leads wie in der Ergebnisliste der App (höchstens leads_requested). Während die Suche läuft, der Stand bis jetzt",
                            "minimum": 0
                          },
                          "message": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Hinweis wie in der App: Grund bei failed, Erklärung wenn weniger Leads als gewünscht gefunden wurden. Nie eine technische Meldung"
                          },
                          "list_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zielliste, in die die App die Treffer speichert",
                            "format": "uuid"
                          },
                          "created_by": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Team-Mitglied, das die Suche gestartet hat (GET /v1/team). Die App erfasst das bisher nicht, dann null",
                            "format": "uuid"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Start der Suche (ISO 8601, UTC)",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzte Änderung am Suchauftrag (ISO 8601, UTC)",
                            "format": "date-time"
                          },
                          "finished_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Ende der Suche, null solange sie wartet oder läuft",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Neueste Suchen",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "2b8c4d6e-1f3a-4b5c-9d7e-8f0a1b2c3d4e",
                          "kind": "web",
                          "status": "running",
                          "query": "Steuerberater",
                          "filters": {
                            "location": "Köln",
                            "industry": "Beratung & Consulting",
                            "country": "de",
                            "language": "de",
                            "time_range": null,
                            "company_websites_only": true,
                            "exclude_existing_leads": true,
                            "single_decision_maker_only": true,
                            "required_data": [],
                            "domain_keywords": [],
                            "exclude_keywords": null,
                            "target_audience": null
                          },
                          "leads_requested": 50,
                          "leads_found": 8,
                          "message": null,
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "created_by": null,
                          "created_at": "2026-10-18T08:02:40.117Z",
                          "updated_at": "2026-10-18T08:05:03.640Z",
                          "finished_at": null
                        },
                        {
                          "id": "7d3e9b21-4c5a-4f6e-8a1b-2c3d4e5f6a7b",
                          "kind": "web",
                          "status": "succeeded",
                          "query": "Pflegedienst",
                          "filters": {
                            "location": "Hamburg",
                            "industry": "Gesundheitswesen",
                            "country": "de",
                            "language": "de",
                            "time_range": null,
                            "company_websites_only": true,
                            "exclude_existing_leads": true,
                            "single_decision_maker_only": true,
                            "required_data": [
                              "phone"
                            ],
                            "domain_keywords": [
                              "pflege"
                            ],
                            "exclude_keywords": "Stellenangebot",
                            "target_audience": "Ambulante Pflegedienste mit 10 bis 50 Mitarbeitenden"
                          },
                          "leads_requested": 20,
                          "leads_found": 14,
                          "message": "Es wurden nur 14 von 20 gewünschten Leads gefunden. Mögliche Gründe: strenge Filter (z. B. „Nur Unternehmenswebsites“, Pflicht-Telefon oder Pflicht-Adresse) oder ein kleiner lokaler Markt.",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "created_by": null,
                          "created_at": "2026-10-17T09:30:12.418Z",
                          "updated_at": "2026-10-17T09:41:55.902Z",
                          "finished_at": "2026-10-17T09:41:55.902Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Nur fertige Suchen",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "7d3e9b21-4c5a-4f6e-8a1b-2c3d4e5f6a7b",
                          "kind": "web",
                          "status": "succeeded",
                          "query": "Pflegedienst",
                          "filters": {
                            "location": "Hamburg",
                            "industry": "Gesundheitswesen",
                            "country": "de",
                            "language": "de",
                            "time_range": null,
                            "company_websites_only": true,
                            "exclude_existing_leads": true,
                            "single_decision_maker_only": true,
                            "required_data": [
                              "phone"
                            ],
                            "domain_keywords": [
                              "pflege"
                            ],
                            "exclude_keywords": "Stellenangebot",
                            "target_audience": "Ambulante Pflegedienste mit 10 bis 50 Mitarbeitenden"
                          },
                          "leads_requested": 20,
                          "leads_found": 14,
                          "message": "Es wurden nur 14 von 20 gewünschten Leads gefunden. Mögliche Gründe: strenge Filter (z. B. „Nur Unternehmenswebsites“, Pflicht-Telefon oder Pflicht-Adresse) oder ein kleiner lokaler Markt.",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "created_by": null,
                          "created_at": "2026-10-17T09:30:12.418Z",
                          "updated_at": "2026-10-17T09:41:55.902Z",
                          "finished_at": "2026-10-17T09:41:55.902Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "outreach.lead_scout.search",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/lead-scout/searches/{id}": {
      "get": {
        "operationId": "getLeadScoutSearch",
        "tags": [
          "Lead Scout"
        ],
        "summary": "Eine Lead-Scout-Suche mit Kennzahlen",
        "description": "Eine Suche wie in der Liste, dazu die Zahlen der Ergebnisseite der App: gefundene Websites, davon nicht passende und Leads mit anderem Standort. Zum Warten auf eine laufende Suche etwa alle 10 Sekunden abfragen, bis `status` succeeded oder failed ist. Die Treffer selbst liefert `GET /v1/lead-scout/searches/{id}/results`.\n\nDie Suchen entstehen in der App unter Lead Scout > Google-Suche (oder im Assistenten). Über die API lassen sie sich nur lesen: Starten kostet Websuche ohne Credits und Speichern kostet 2 Credits je Lead, beides bleibt in der App. Abfragen kostet nichts.\n\nJedes Mitglied mit dem Recht für den Lead Scout sieht alle Suchen des Kontos, wie in der App. Suchen, die in der App entfernt wurden, fehlen.\n\n**Berechtigung:** `read:leads`\n\n**Recht in dealsky:** `outreach.lead_scout.search` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Suche",
              "format": "uuid"
            },
            "description": "ID der Suche"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "7d3e9b21-4c5a-4f6e-8a1b-2c3d4e5f6a7b",
                          "kind": "web",
                          "status": "succeeded",
                          "query": "Pflegedienst",
                          "filters": {
                            "location": "Hamburg",
                            "industry": "Gesundheitswesen",
                            "country": "de",
                            "language": "de",
                            "time_range": null,
                            "company_websites_only": true,
                            "exclude_existing_leads": true,
                            "single_decision_maker_only": true,
                            "required_data": [
                              "phone"
                            ],
                            "domain_keywords": [
                              "pflege"
                            ],
                            "exclude_keywords": "Stellenangebot",
                            "target_audience": "Ambulante Pflegedienste mit 10 bis 50 Mitarbeitenden"
                          },
                          "leads_requested": 20,
                          "leads_found": 14,
                          "message": "Es wurden nur 14 von 20 gewünschten Leads gefunden. Mögliche Gründe: strenge Filter (z. B. „Nur Unternehmenswebsites“, Pflicht-Telefon oder Pflicht-Adresse) oder ein kleiner lokaler Markt.",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "created_by": null,
                          "created_at": "2026-10-17T09:30:12.418Z",
                          "updated_at": "2026-10-17T09:41:55.902Z",
                          "finished_at": "2026-10-17T09:41:55.902Z",
                          "websites_found": 63,
                          "not_matching": 31,
                          "other_location": 0
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Suche",
                          "format": "uuid"
                        },
                        "kind": {
                          "type": "string",
                          "description": "Art der Suche: web ist die Google-Suche mit Auswertung der Firmenwebsites (in der App „Google-Suche“)",
                          "enum": [
                            "web"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "description": "queued wartet, running sucht und wertet Websites aus, succeeded ist fertig, failed ist gescheitert",
                          "enum": [
                            "queued",
                            "running",
                            "succeeded",
                            "failed"
                          ]
                        },
                        "query": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Suchbegriff"
                        },
                        "filters": {
                          "type": "object",
                          "description": "Suchparameter in Kurzform",
                          "properties": {
                            "location": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ort der Suche"
                            },
                            "industry": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Branche, null ohne Einschränkung"
                            },
                            "country": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Land der Google-Suche, z. B. de"
                            },
                            "language": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Sprache der Google-Suche, z. B. de"
                            },
                            "time_range": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Nur Seiten aus diesem Zeitraum (hour, day, week, month, year), null für alle Zeiten",
                              "enum": [
                                "hour",
                                "day",
                                "week",
                                "month",
                                "year",
                                null
                              ]
                            },
                            "company_websites_only": {
                              "type": "boolean",
                              "description": "Nur Unternehmenswebsites (mit Impressum), keine Verzeichnisse und Portale"
                            },
                            "exclude_existing_leads": {
                              "type": "boolean",
                              "description": "Firmen, die schon als Lead im Konto stehen, wurden übersprungen"
                            },
                            "single_decision_maker_only": {
                              "type": "boolean",
                              "description": "Nur ein Entscheider je Firma"
                            },
                            "required_data": {
                              "type": "array",
                              "description": "Zusätzlich verlangte Angaben: address (vollständige Adresse für Briefe), phone (Telefon). Firma, Entscheider und E-Mail sind immer Pflicht",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "address",
                                  "phone"
                                ]
                              }
                            },
                            "domain_keywords": {
                              "type": "array",
                              "description": "Begriffe, die in der Domain vorkommen müssen",
                              "items": {
                                "type": "string"
                              }
                            },
                            "exclude_keywords": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ausgeschlossene Begriffe"
                            },
                            "target_audience": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Beschreibung der Zielgruppe, gegen die die KI die Treffer geprüft hat"
                            }
                          },
                          "additionalProperties": false
                        },
                        "leads_requested": {
                          "type": "integer",
                          "description": "Gewünschte Anzahl Leads",
                          "minimum": 1
                        },
                        "leads_found": {
                          "type": "integer",
                          "description": "Gefundene Leads wie in der Ergebnisliste der App (höchstens leads_requested). Während die Suche läuft, der Stand bis jetzt",
                          "minimum": 0
                        },
                        "message": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Hinweis wie in der App: Grund bei failed, Erklärung wenn weniger Leads als gewünscht gefunden wurden. Nie eine technische Meldung"
                        },
                        "list_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zielliste, in die die App die Treffer speichert",
                          "format": "uuid"
                        },
                        "created_by": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Team-Mitglied, das die Suche gestartet hat (GET /v1/team). Die App erfasst das bisher nicht, dann null",
                          "format": "uuid"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Start der Suche (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte Änderung am Suchauftrag (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "finished_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Ende der Suche, null solange sie wartet oder läuft",
                          "format": "date-time"
                        },
                        "websites_found": {
                          "type": "integer",
                          "description": "Websites, die die Suche gefunden hat (in der App „URLs gefunden“)",
                          "minimum": 0
                        },
                        "not_matching": {
                          "type": "integer",
                          "description": "Davon nicht passend: Verzeichnis, Job-Portal, kein Impressum, anderer Standort, von der KI als unpassend erkannt oder nicht lesbar (in der App „nicht passend“)",
                          "minimum": 0
                        },
                        "other_location": {
                          "type": "integer",
                          "description": "Gefundene Leads mit abweichendem Standort (in der App „anderer Standort“)",
                          "minimum": 0
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Fertige Suche mit weniger Leads als gewünscht",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "7d3e9b21-4c5a-4f6e-8a1b-2c3d4e5f6a7b",
                        "kind": "web",
                        "status": "succeeded",
                        "query": "Pflegedienst",
                        "filters": {
                          "location": "Hamburg",
                          "industry": "Gesundheitswesen",
                          "country": "de",
                          "language": "de",
                          "time_range": null,
                          "company_websites_only": true,
                          "exclude_existing_leads": true,
                          "single_decision_maker_only": true,
                          "required_data": [
                            "phone"
                          ],
                          "domain_keywords": [
                            "pflege"
                          ],
                          "exclude_keywords": "Stellenangebot",
                          "target_audience": "Ambulante Pflegedienste mit 10 bis 50 Mitarbeitenden"
                        },
                        "leads_requested": 20,
                        "leads_found": 14,
                        "message": "Es wurden nur 14 von 20 gewünschten Leads gefunden. Mögliche Gründe: strenge Filter (z. B. „Nur Unternehmenswebsites“, Pflicht-Telefon oder Pflicht-Adresse) oder ein kleiner lokaler Markt.",
                        "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "created_by": null,
                        "created_at": "2026-10-17T09:30:12.418Z",
                        "updated_at": "2026-10-17T09:41:55.902Z",
                        "finished_at": "2026-10-17T09:41:55.902Z",
                        "websites_found": 63,
                        "not_matching": 31,
                        "other_location": 0
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:leads",
        "x-dealsky-permission": "outreach.lead_scout.search",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/leads/{id}/notes": {
      "get": {
        "operationId": "listLeadNotes",
        "tags": [
          "CRM"
        ],
        "summary": "Notizen eines Leads",
        "description": "Neueste zuerst, wie im Notizen-Reiter der App. Enthält Notizen aus der App, aus dem CSV-Import und über die API. Andere Einträge des Verlaufs liefert GET /v1/leads/{id}/activities.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
                            "content": "Ruft nach der Messe zurück, Interesse an Paket Business.",
                            "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                            "created_by_type": "api",
                            "created_at": "2026-10-18T09:12:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Notiz",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "content": {
                            "type": "string",
                            "description": "Text der Notiz",
                            "minLength": 1,
                            "maxLength": 10000
                          },
                          "created_by": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Team-Mitglied, das die Notiz angelegt hat (bei der API: wer den Key erzeugt hat)",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "created_by_type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "user (in der App angelegt) oder api",
                            "readOnly": true
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt der Anlage",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
                          "content": "Ruft nach der Messe zurück, Interesse an Paket Business.",
                          "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                          "created_by_type": "api",
                          "created_at": "2026-10-18T09:12:00.000Z"
                        },
                        {
                          "id": "4d5e6f7a-8b9c-4d0e-9f1a-2b3c4d5e6f70",
                          "content": "Erstkontakt auf der Messe",
                          "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                          "created_by_type": "user",
                          "created_at": "2026-10-16T15:40:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      },
      "post": {
        "operationId": "createLeadNote",
        "tags": [
          "CRM"
        ],
        "summary": "Notiz an einem Lead anlegen",
        "description": "Legt eine Notiz an wie „Notiz hinzufügen“ im Lead-Panel. Sie erscheint im Notizen-Reiter und im Verlauf des Leads. Als Ersteller gilt die Person, die den API-Key erzeugt hat. Weitere Wirkung hat das Anlegen nicht.\n\n**Berechtigung:** `write:crm`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "content": {
                    "type": "string",
                    "description": "Text der Notiz",
                    "minLength": 1,
                    "maxLength": 10000
                  }
                },
                "required": [
                  "content"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "content": "Ruft nach der Messe zurück, Interesse an Paket Business."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
                          "content": "Ruft nach der Messe zurück, Interesse an Paket Business.",
                          "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                          "created_by_type": "api",
                          "created_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Notiz",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "content": {
                          "type": "string",
                          "description": "Text der Notiz",
                          "minLength": 1,
                          "maxLength": 10000
                        },
                        "created_by": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Team-Mitglied, das die Notiz angelegt hat (bei der API: wer den Key erzeugt hat)",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "created_by_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "user (in der App angelegt) oder api",
                          "readOnly": true
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
                        "content": "Ruft nach der Messe zurück, Interesse an Paket Business.",
                        "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                        "created_by_type": "api",
                        "created_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:crm",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/leads/{id}/notes/{note_id}": {
      "delete": {
        "operationId": "deleteLeadNote",
        "tags": [
          "CRM"
        ],
        "summary": "Notiz löschen",
        "description": "Löscht die Notiz endgültig, wie das Papierkorb-Symbol im Notizen-Reiter. Wie in der App darf das jede Person mit dem Recht, Leads zu bearbeiten, nicht nur der Ersteller. Andere Einträge des Verlaufs lassen sich hier nicht löschen.\n\n**Berechtigung:** `delete:crm`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Löscht endgültig. Nicht umkehrbar.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          },
          {
            "name": "note_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Notiz",
              "format": "uuid"
            },
            "description": "ID der Notiz"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "true: Die Notiz wurde gelöscht"
                        },
                        "id": {
                          "type": "string",
                          "description": "ID der gelöschten Notiz",
                          "format": "uuid"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "deleted": true,
                        "id": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "delete:crm",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "destructive"
      }
    },
    "/v1/leads/{id}/follow-up": {
      "get": {
        "operationId": "getLeadFollowUp",
        "tags": [
          "CRM"
        ],
        "summary": "Wiedervorlage eines Leads lesen",
        "description": "Zeitpunkt, Notiz, Grund und Zahl der Nachfass-Versuche, wie sie die App unter „Wiedervorlage“ zeigt. snoozed_until null heißt: keine Wiedervorlage gesetzt.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "status": "follow_up",
                          "snoozed_until": "2026-10-21T07:00:00.000Z",
                          "follow_up_note": "Angebot wird geprüft, Dienstag nachfassen",
                          "follow_up_reason": "proposal_review",
                          "follow_up_attempts": 2
                        }
                      ],
                      "properties": {
                        "lead_id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "description": "Vertriebsstatus des Leads. Eine Wiedervorlage setzt ihn wie die App auf follow_up."
                        },
                        "snoozed_until": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der Wiedervorlage. null = keine Wiedervorlage",
                          "format": "date-time"
                        },
                        "follow_up_note": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Notiz zur Wiedervorlage"
                        },
                        "follow_up_reason": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Grund der Wiedervorlage",
                          "enum": [
                            "scheduling",
                            "no_show_setting",
                            "no_show_closing",
                            "decision_pending",
                            "stakeholder_review",
                            "callback_requested",
                            "proposal_review",
                            null
                          ]
                        },
                        "follow_up_attempts": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Zahl der Nachfass-Versuche"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "status": "follow_up",
                        "snoozed_until": "2026-10-21T07:00:00.000Z",
                        "follow_up_note": "Angebot wird geprüft, Dienstag nachfassen",
                        "follow_up_reason": "proposal_review",
                        "follow_up_attempts": 2
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read"
      },
      "put": {
        "operationId": "setLeadFollowUp",
        "tags": [
          "CRM"
        ],
        "summary": "Wiedervorlage setzen",
        "description": "Setzt die Wiedervorlage wie „Wiedervorlage“ im Lead-Panel: Zeitpunkt `snoozed_until` und, wie in der App immer, den Status `follow_up`. Zum Zeitpunkt erscheint der Lead im CRM als fällig.\n\n`follow_up_note` und `follow_up_reason` werden nur geändert, wenn sie übergeben werden; `null` leert sie. `count_attempt: true` zählt wie beim Gesprächsende einen Nachfass-Versuch hoch.\n\nDen nächsten Schritt (`next_action`, `next_action_at`) setzt die Wiedervorlage in der App nicht; er bleibt über PATCH /v1/leads/{id} änderbar.\n\nWirkt nicht nach außen: Eine laufende Kampagne oder Sequenz des Leads läuft unverändert weiter, es wird nichts gesendet. Kostet keine Credits.\n\n**Berechtigung:** `write:crm`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "snoozed_until": {
                    "type": "string",
                    "description": "Zeitpunkt der Wiedervorlage, z. B. 2026-10-21T09:00:00+02:00",
                    "format": "date-time"
                  },
                  "follow_up_note": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Notiz zur Wiedervorlage. Nicht übergeben = bleibt, null = leeren",
                    "maxLength": 5000
                  },
                  "follow_up_reason": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Grund: scheduling (Terminfindung), no_show_setting, no_show_closing, decision_pending (Entscheidung ausstehend), stakeholder_review (Rücksprache mit Team), callback_requested (Rückruf vereinbart), proposal_review (Angebot wird geprüft). Nicht übergeben = bleibt, null = leeren",
                    "enum": [
                      "scheduling",
                      "no_show_setting",
                      "no_show_closing",
                      "decision_pending",
                      "stakeholder_review",
                      "callback_requested",
                      "proposal_review",
                      null
                    ]
                  },
                  "count_attempt": {
                    "type": "boolean",
                    "description": "true: Nachfass-Versuche um 1 erhöhen (Standard: false)"
                  }
                },
                "required": [
                  "snoozed_until"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "snoozed_until": "2026-10-21T09:00:00+02:00",
                    "follow_up_note": "Angebot wird geprüft, Dienstag nachfassen",
                    "follow_up_reason": "proposal_review",
                    "count_attempt": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "status": "follow_up",
                          "snoozed_until": "2026-10-21T07:00:00.000Z",
                          "follow_up_note": "Angebot wird geprüft, Dienstag nachfassen",
                          "follow_up_reason": "proposal_review",
                          "follow_up_attempts": 2
                        }
                      ],
                      "properties": {
                        "lead_id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "description": "Vertriebsstatus des Leads. Eine Wiedervorlage setzt ihn wie die App auf follow_up."
                        },
                        "snoozed_until": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der Wiedervorlage. null = keine Wiedervorlage",
                          "format": "date-time"
                        },
                        "follow_up_note": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Notiz zur Wiedervorlage"
                        },
                        "follow_up_reason": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Grund der Wiedervorlage",
                          "enum": [
                            "scheduling",
                            "no_show_setting",
                            "no_show_closing",
                            "decision_pending",
                            "stakeholder_review",
                            "callback_requested",
                            "proposal_review",
                            null
                          ]
                        },
                        "follow_up_attempts": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Zahl der Nachfass-Versuche"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "status": "follow_up",
                        "snoozed_until": "2026-10-21T07:00:00.000Z",
                        "follow_up_note": "Angebot wird geprüft, Dienstag nachfassen",
                        "follow_up_reason": "proposal_review",
                        "follow_up_attempts": 2
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:crm",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      },
      "delete": {
        "operationId": "clearLeadFollowUp",
        "tags": [
          "CRM"
        ],
        "summary": "Wiedervorlage entfernen",
        "description": "Wie „Wiedervorlage entfernen“ in der App: Zeitpunkt und Notiz werden geleert, Grund und Status bleiben. Mit `reset_attempts=true` stehen die Nachfass-Versuche wieder auf 0. Wirkt nicht nach außen: Eine laufende Kampagne oder Sequenz des Leads läuft unverändert weiter, es wird nichts gesendet. Kostet keine Credits.\n\n**Berechtigung:** `write:crm`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          },
          {
            "name": "reset_attempts",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Nachfass-Versuche auf 0 setzen (Standard: false)"
            },
            "description": "Nachfass-Versuche auf 0 setzen (Standard: false)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "status": "follow_up",
                          "snoozed_until": "2026-10-21T07:00:00.000Z",
                          "follow_up_note": "Angebot wird geprüft, Dienstag nachfassen",
                          "follow_up_reason": "proposal_review",
                          "follow_up_attempts": 2
                        }
                      ],
                      "properties": {
                        "lead_id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "description": "Vertriebsstatus des Leads. Eine Wiedervorlage setzt ihn wie die App auf follow_up."
                        },
                        "snoozed_until": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der Wiedervorlage. null = keine Wiedervorlage",
                          "format": "date-time"
                        },
                        "follow_up_note": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Notiz zur Wiedervorlage"
                        },
                        "follow_up_reason": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Grund der Wiedervorlage",
                          "enum": [
                            "scheduling",
                            "no_show_setting",
                            "no_show_closing",
                            "decision_pending",
                            "stakeholder_review",
                            "callback_requested",
                            "proposal_review",
                            null
                          ]
                        },
                        "follow_up_attempts": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Zahl der Nachfass-Versuche"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "status": "follow_up",
                        "snoozed_until": null,
                        "follow_up_note": null,
                        "follow_up_reason": "proposal_review",
                        "follow_up_attempts": 2
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:crm",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/leads/{id}/meeting": {
      "put": {
        "operationId": "setLeadMeeting",
        "tags": [
          "CRM"
        ],
        "summary": "Termin am Lead eintragen",
        "description": "Trägt Zeitpunkt und Art des Termins ein wie der Abschnitt „Termin & Meeting“ im Lead-Panel. Der Termin erscheint im CRM-Termin-Dashboard und in den Termin-Kennzahlen.\n\n`mark_booked: true` setzt zusätzlich den Status `booked` wie „Termin gebucht“ im Status-Menü und entfernt dabei wie die App eine Wiedervorlage (Zeitpunkt, Notiz, Versuche). Steht der Lead schon auf `booked`, bleibt alles andere unverändert.\n\nAnders als „Termin gelegt“ im Postfach oder eine Buchung über Calendly, TidyCal oder die Landingpage stoppt dieser Endpunkt keine Sequenz. Wer die LinkedIn-Sequenz nach einem Termin beenden will, tut das in der App im Postfach. Wirkt nicht nach außen: Eine laufende Kampagne oder Sequenz des Leads läuft unverändert weiter, es wird nichts gesendet. Kostet keine Credits.\n\nEinen Verlaufseintrag schreibt die App hierbei nicht, die API auch nicht.\n\n**Berechtigung:** `write:crm`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scheduled_at": {
                    "type": "string",
                    "description": "Zeitpunkt des Termins, z. B. 2026-10-22T10:30:00+02:00",
                    "format": "date-time"
                  },
                  "meeting_type": {
                    "type": "string",
                    "description": "setting (Setting-Call), closing (Closing-Call), demo (Demo/Präsentation) oder other (Sonstiges)",
                    "enum": [
                      "setting",
                      "closing",
                      "demo",
                      "other"
                    ]
                  },
                  "mark_booked": {
                    "type": "boolean",
                    "description": "true: Status auf booked setzen (Standard: false)"
                  }
                },
                "required": [
                  "scheduled_at",
                  "meeting_type"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "scheduled_at": "2026-10-22T10:30:00+02:00",
                    "meeting_type": "setting",
                    "mark_booked": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "meeting_scheduled_at": "2026-10-22T08:30:00.000Z",
                          "meeting_type": "setting",
                          "status": "booked"
                        }
                      ],
                      "properties": {
                        "lead_id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "format": "uuid"
                        },
                        "meeting_scheduled_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt des Termins",
                          "format": "date-time"
                        },
                        "meeting_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "setting, closing, demo oder other",
                          "enum": [
                            "setting",
                            "closing",
                            "demo",
                            "other",
                            null
                          ]
                        },
                        "status": {
                          "type": "string",
                          "description": "Vertriebsstatus des Leads"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "meeting_scheduled_at": "2026-10-22T08:30:00.000Z",
                        "meeting_type": "setting",
                        "status": "booked"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:crm",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      },
      "delete": {
        "operationId": "clearLeadMeeting",
        "tags": [
          "CRM"
        ],
        "summary": "Termin am Lead entfernen",
        "description": "Leert Zeitpunkt und Art des Termins. Der Status bleibt (ein `booked` lässt sich über PATCH /v1/leads/{id} ändern), ebenso die Zeitpunkte für durchgeführtes Setting und Closing. Wirkt nicht nach außen: Eine laufende Kampagne oder Sequenz des Leads läuft unverändert weiter, es wird nichts gesendet. Kostet keine Credits.\n\n**Berechtigung:** `write:crm`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "meeting_scheduled_at": "2026-10-22T08:30:00.000Z",
                          "meeting_type": "setting",
                          "status": "booked"
                        }
                      ],
                      "properties": {
                        "lead_id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "format": "uuid"
                        },
                        "meeting_scheduled_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt des Termins",
                          "format": "date-time"
                        },
                        "meeting_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "setting, closing, demo oder other",
                          "enum": [
                            "setting",
                            "closing",
                            "demo",
                            "other",
                            null
                          ]
                        },
                        "status": {
                          "type": "string",
                          "description": "Vertriebsstatus des Leads"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "meeting_scheduled_at": null,
                        "meeting_type": null,
                        "status": "booked"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:crm",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/leads/{id}/calls": {
      "get": {
        "operationId": "listLeadCalls",
        "tags": [
          "CRM"
        ],
        "summary": "Telefonate eines Leads",
        "description": "Protokollierte Anrufe, neueste zuerst, wie im Reiter Anrufe des Lead-Panels: aus der Calling Engine, aus der App protokolliert und über die API. Ohne Aufnahmen und Telefonnummern.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
                            "called_at": "2026-10-18T08:15:00.000Z",
                            "direction": "outbound",
                            "outcome": "reached_decision_maker",
                            "duration_seconds": 420,
                            "spoke_with_type": "decision_maker",
                            "spoke_with_name": "Max Mustermann",
                            "notes": "Interesse an Paket Business, Angebot bis Freitag schicken.",
                            "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                            "created_at": "2026-10-18T08:23:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Anruf-Eintrags",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "called_at": {
                            "type": "string",
                            "description": "Zeitpunkt des Anrufs. Standard: jetzt",
                            "format": "date-time"
                          },
                          "direction": {
                            "type": "string",
                            "description": "outbound (ausgehend, Standard) oder inbound (eingehend)",
                            "enum": [
                              "outbound",
                              "inbound"
                            ]
                          },
                          "outcome": {
                            "type": "string",
                            "description": "Ergebnis: reached_decision_maker (Entscheider erreicht), reached_gatekeeper (Gatekeeper erreicht), reached_other (andere Person erreicht), voicemail (Mailbox), not_reached (nicht erreicht), wrong_number (falsche Nummer), callback_requested (Rückruf erbeten)",
                            "enum": [
                              "reached_decision_maker",
                              "reached_gatekeeper",
                              "reached_other",
                              "voicemail",
                              "not_reached",
                              "wrong_number",
                              "callback_requested"
                            ]
                          },
                          "duration_seconds": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Dauer in Sekunden",
                            "minimum": 0,
                            "maximum": 86400
                          },
                          "spoke_with_type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Gesprochen mit: decision_maker, gatekeeper, assistant, colleague oder unknown",
                            "enum": [
                              "decision_maker",
                              "gatekeeper",
                              "assistant",
                              "colleague",
                              "unknown",
                              null
                            ]
                          },
                          "spoke_with_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Name der Person am Telefon",
                            "maxLength": 200
                          },
                          "notes": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Notiz zum Anruf, erscheint auch im Verlauf",
                            "maxLength": 10000
                          },
                          "created_by": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Team-Mitglied, das den Anruf protokolliert hat (bei der API: wer den Key erzeugt hat)",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt, zu dem der Anruf protokolliert wurde (kann von called_at abweichen)",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
                          "called_at": "2026-10-18T08:15:00.000Z",
                          "direction": "outbound",
                          "outcome": "reached_decision_maker",
                          "duration_seconds": 420,
                          "spoke_with_type": "decision_maker",
                          "spoke_with_name": "Max Mustermann",
                          "notes": "Interesse an Paket Business, Angebot bis Freitag schicken.",
                          "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                          "created_at": "2026-10-18T08:23:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      },
      "post": {
        "operationId": "logLeadCall",
        "tags": [
          "CRM"
        ],
        "summary": "Telefonat protokollieren",
        "description": "Protokolliert einen Anruf wie „Ausgehender Anruf protokollieren“ bzw. „Eingehender Anruf protokollieren“ im Lead-Panel: Der Anruf steht danach im Reiter Anrufe und als „Anruf durchgeführt“ im Verlauf; am Lead werden letzter Anruf, letztes Ergebnis und die Zahl der Anrufe fortgeschrieben.\n\nWie in der App ändert das Protokoll weder den Status noch die Wiedervorlage (dafür PUT /v1/leads/{id}/follow-up). Als Ersteller gilt die Person, die den API-Key erzeugt hat. Es wird nicht telefoniert. Wirkt nicht nach außen: Eine laufende Kampagne oder Sequenz des Leads läuft unverändert weiter, es wird nichts gesendet. Kostet keine Credits.\n\n**Berechtigung:** `write:crm`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "outcome": {
                    "type": "string",
                    "description": "Ergebnis: reached_decision_maker (Entscheider erreicht), reached_gatekeeper (Gatekeeper erreicht), reached_other (andere Person erreicht), voicemail (Mailbox), not_reached (nicht erreicht), wrong_number (falsche Nummer), callback_requested (Rückruf erbeten)",
                    "enum": [
                      "reached_decision_maker",
                      "reached_gatekeeper",
                      "reached_other",
                      "voicemail",
                      "not_reached",
                      "wrong_number",
                      "callback_requested"
                    ]
                  },
                  "direction": {
                    "type": "string",
                    "description": "outbound (ausgehend, Standard) oder inbound (eingehend)",
                    "enum": [
                      "outbound",
                      "inbound"
                    ]
                  },
                  "called_at": {
                    "type": "string",
                    "description": "Zeitpunkt des Anrufs. Standard: jetzt",
                    "format": "date-time"
                  },
                  "duration_seconds": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "Dauer in Sekunden",
                    "minimum": 0,
                    "maximum": 86400
                  },
                  "spoke_with_type": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Gesprochen mit: decision_maker, gatekeeper, assistant, colleague oder unknown",
                    "enum": [
                      "decision_maker",
                      "gatekeeper",
                      "assistant",
                      "colleague",
                      "unknown",
                      null
                    ]
                  },
                  "spoke_with_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Name der Person am Telefon",
                    "maxLength": 200
                  },
                  "notes": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Notiz zum Anruf, erscheint auch im Verlauf",
                    "maxLength": 10000
                  }
                },
                "required": [
                  "outcome"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "outcome": "reached_decision_maker",
                    "called_at": "2026-10-18T10:15:00+02:00",
                    "duration_seconds": 420,
                    "spoke_with_type": "decision_maker",
                    "spoke_with_name": "Max Mustermann",
                    "notes": "Interesse an Paket Business, Angebot bis Freitag schicken."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
                          "called_at": "2026-10-18T08:15:00.000Z",
                          "direction": "outbound",
                          "outcome": "reached_decision_maker",
                          "duration_seconds": 420,
                          "spoke_with_type": "decision_maker",
                          "spoke_with_name": "Max Mustermann",
                          "notes": "Interesse an Paket Business, Angebot bis Freitag schicken.",
                          "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                          "created_at": "2026-10-18T08:23:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Anruf-Eintrags",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "called_at": {
                          "type": "string",
                          "description": "Zeitpunkt des Anrufs. Standard: jetzt",
                          "format": "date-time"
                        },
                        "direction": {
                          "type": "string",
                          "description": "outbound (ausgehend, Standard) oder inbound (eingehend)",
                          "enum": [
                            "outbound",
                            "inbound"
                          ]
                        },
                        "outcome": {
                          "type": "string",
                          "description": "Ergebnis: reached_decision_maker (Entscheider erreicht), reached_gatekeeper (Gatekeeper erreicht), reached_other (andere Person erreicht), voicemail (Mailbox), not_reached (nicht erreicht), wrong_number (falsche Nummer), callback_requested (Rückruf erbeten)",
                          "enum": [
                            "reached_decision_maker",
                            "reached_gatekeeper",
                            "reached_other",
                            "voicemail",
                            "not_reached",
                            "wrong_number",
                            "callback_requested"
                          ]
                        },
                        "duration_seconds": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Dauer in Sekunden",
                          "minimum": 0,
                          "maximum": 86400
                        },
                        "spoke_with_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Gesprochen mit: decision_maker, gatekeeper, assistant, colleague oder unknown",
                          "enum": [
                            "decision_maker",
                            "gatekeeper",
                            "assistant",
                            "colleague",
                            "unknown",
                            null
                          ]
                        },
                        "spoke_with_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Name der Person am Telefon",
                          "maxLength": 200
                        },
                        "notes": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Notiz zum Anruf, erscheint auch im Verlauf",
                          "maxLength": 10000
                        },
                        "created_by": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Team-Mitglied, das den Anruf protokolliert hat (bei der API: wer den Key erzeugt hat)",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt, zu dem der Anruf protokolliert wurde (kann von called_at abweichen)",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
                        "called_at": "2026-10-18T08:15:00.000Z",
                        "direction": "outbound",
                        "outcome": "reached_decision_maker",
                        "duration_seconds": 420,
                        "spoke_with_type": "decision_maker",
                        "spoke_with_name": "Max Mustermann",
                        "notes": "Interesse an Paket Business, Angebot bis Freitag schicken.",
                        "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                        "created_at": "2026-10-18T08:23:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:crm",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/calls": {
      "get": {
        "operationId": "listCalls",
        "tags": [
          "CRM"
        ],
        "summary": "Anrufe über alle Leads",
        "description": "Alle protokollierten Anrufe des Kontos, neueste zuerst: aus der Calling Engine, im Lead-Panel protokolliert und über POST /v1/leads/{id}/calls. Jeder Eintrag ist derselbe wie unter GET /v1/leads/{id}/calls, dazu `lead_id`. Ergebnis und Gesprächspartner sind dieselben Angaben, die das CRM-Dashboard im Reiter Anrufe zählt.\n\nFilter: `from` (einschließlich) und `to` (ausschließlich) beziehen sich auf den Zeitpunkt des Anrufs; `outcome` (eines oder mehrere, kommagetrennt), `direction`, `lead_id` und `user_id` (wer den Anruf protokolliert hat, wie der Filter Mitarbeiter in der App). Ohne Filter liefert die API die Anrufe des ganzen Kontos, wie die App sie jedem mit CRM-Zugang zeigt.\n\nOhne Aufnahmen, Mitschriften und Telefonnummern: Die technischen Verbindungen der Browser-Telefonie (Wählversuche unter CRM, Verbindungen, mit Gegennummer, Aufnahme und Twilio-Kennungen) gibt die API nicht heraus. Liest nur, kostet nichts.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** `crm` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Anrufe ab diesem Zeitpunkt",
              "format": "date-time"
            },
            "description": "Nur Anrufe ab diesem Zeitpunkt"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Anrufe vor diesem Zeitpunkt",
              "format": "date-time"
            },
            "description": "Nur Anrufe vor diesem Zeitpunkt"
          },
          {
            "name": "outcome",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Ein oder mehrere Ergebnisse, kommagetrennt, z. B. reached_decision_maker,callback_requested",
              "items": {
                "type": "string",
                "enum": [
                  "reached_decision_maker",
                  "reached_gatekeeper",
                  "reached_other",
                  "voicemail",
                  "not_reached",
                  "wrong_number",
                  "callback_requested"
                ]
              },
              "maxItems": 7
            },
            "description": "Ein oder mehrere Ergebnisse, kommagetrennt, z. B. reached_decision_maker,callback_requested",
            "style": "form",
            "explode": false
          },
          {
            "name": "direction",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "outbound (ausgehend) oder inbound (eingehend)",
              "enum": [
                "outbound",
                "inbound"
              ]
            },
            "description": "outbound (ausgehend) oder inbound (eingehend)"
          },
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Anrufe, die dieses Team-Mitglied protokolliert hat (GET /v1/team)",
              "format": "uuid"
            },
            "description": "Nur Anrufe, die dieses Team-Mitglied protokolliert hat (GET /v1/team)"
          },
          {
            "name": "lead_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Anrufe dieses Leads",
              "format": "uuid"
            },
            "description": "Nur Anrufe dieses Leads"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
                            "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                            "called_at": "2026-10-18T08:15:00.000Z",
                            "direction": "outbound",
                            "outcome": "reached_decision_maker",
                            "duration_seconds": 420,
                            "spoke_with_type": "decision_maker",
                            "spoke_with_name": "Max Mustermann",
                            "notes": "Interesse an Paket Business, Angebot bis Freitag schicken.",
                            "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                            "created_at": "2026-10-18T08:23:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Anrufs",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "lead_id": {
                            "type": "string",
                            "description": "Lead, zu dem der Anruf gehört (GET /v1/leads/{id})",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "called_at": {
                            "type": "string",
                            "description": "Zeitpunkt des Anrufs. Standard: jetzt",
                            "format": "date-time"
                          },
                          "direction": {
                            "type": "string",
                            "description": "outbound (ausgehend, Standard) oder inbound (eingehend)",
                            "enum": [
                              "outbound",
                              "inbound"
                            ]
                          },
                          "outcome": {
                            "type": "string",
                            "description": "Ergebnis: reached_decision_maker (Entscheider erreicht), reached_gatekeeper (Gatekeeper erreicht), reached_other (andere Person erreicht), voicemail (Mailbox), not_reached (nicht erreicht), wrong_number (falsche Nummer), callback_requested (Rückruf erbeten)",
                            "enum": [
                              "reached_decision_maker",
                              "reached_gatekeeper",
                              "reached_other",
                              "voicemail",
                              "not_reached",
                              "wrong_number",
                              "callback_requested"
                            ]
                          },
                          "duration_seconds": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Dauer in Sekunden",
                            "minimum": 0,
                            "maximum": 86400
                          },
                          "spoke_with_type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Gesprochen mit: decision_maker, gatekeeper, assistant, colleague oder unknown",
                            "enum": [
                              "decision_maker",
                              "gatekeeper",
                              "assistant",
                              "colleague",
                              "unknown",
                              null
                            ]
                          },
                          "spoke_with_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Name der Person am Telefon",
                            "maxLength": 200
                          },
                          "notes": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Notiz zum Anruf, erscheint auch im Verlauf",
                            "maxLength": 10000
                          },
                          "created_by": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Team-Mitglied, das den Anruf protokolliert hat (bei der API: wer den Key erzeugt hat)",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt, zu dem der Anruf protokolliert wurde (kann von called_at abweichen)",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Neueste Anrufe",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "called_at": "2026-10-18T08:15:00.000Z",
                          "direction": "outbound",
                          "outcome": "reached_decision_maker",
                          "duration_seconds": 420,
                          "spoke_with_type": "decision_maker",
                          "spoke_with_name": "Max Mustermann",
                          "notes": "Interesse an Paket Business, Angebot bis Freitag schicken.",
                          "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                          "created_at": "2026-10-18T08:23:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Entscheider erreicht in der Woche ab dem 12. Oktober",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "6e7f8a9b-0c1d-4e2f-8a3b-4c5d6e7f8a9b",
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "called_at": "2026-10-18T08:15:00.000Z",
                          "direction": "outbound",
                          "outcome": "reached_decision_maker",
                          "duration_seconds": 420,
                          "spoke_with_type": "decision_maker",
                          "spoke_with_name": "Max Mustermann",
                          "notes": "Interesse an Paket Business, Angebot bis Freitag schicken.",
                          "created_by": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                          "created_at": "2026-10-18T08:23:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "crm",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/call-scripts": {
      "get": {
        "operationId": "listCallScripts",
        "tags": [
          "CRM"
        ],
        "summary": "Gesprächsleitfäden auflisten",
        "description": "Die Gesprächsleitfäden des Kontos, wie sie die App beim Telefonieren im CRM anzeigt und unter Assets, Gesprächsleitfäden pflegt. Nur aktive: Löschen blendet einen Leitfaden in der App aus. Reihenfolge wie in der App, nach Position, dann Name.\n\n`content` ist der Text mit Platzhaltern in doppelten geschweiften Klammern (z. B. {{first_name}}, {{anrede}}), Abschnitten {{section:Name}} und Entscheidungsknöpfen {{decision:id}}. Die App setzt die Daten des Leads beim Anruf ein, die API liefert den Text unverändert. `for_statuses`, `target_persona` und `conditions` bestimmen, bei welchem Lead die App den Leitfaden vorschlägt.\n\nHat das Konto noch keine Leitfäden, legt die App beim ersten Öffnen Standard-Leitfäden an; die API legt nichts an und liefert dann eine leere Liste. Anlegen und ändern geht nur in der App. Liest nur, kostet nichts.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** `crm` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "2f3e4d5c-6b7a-4891-8a0b-1c2d3e4f5a6b",
                            "name": "Entscheider Skript",
                            "description": "Nachdem man zum Entscheider durchgestellt wurde",
                            "call_type": "standard",
                            "for_statuses": [
                              "open",
                              "contacted",
                              "not_reached",
                              "interested"
                            ],
                            "target_persona": "decision_maker",
                            "content": "Hallo {{anrede}} {{last_name}},\n\nhier ist {{my_first_name}} von Muster GmbH.\n\n{{section:Pitch}}\nWir haben Ihnen neulich eine persönliche Videonachricht gesendet. Hatten Sie schon die Möglichkeit, sie anzuschauen?\n\n{{decision:interesse}}",
                            "questions": [
                              {
                                "id": "q1",
                                "question": "Wie viele Vertriebler im Team?",
                                "type": "number",
                                "required": false
                              }
                            ],
                            "inline_decisions": [
                              {
                                "id": "interesse",
                                "question": "Hat der Kontakt Interesse?",
                                "options": [
                                  {
                                    "id": "ja",
                                    "label": "Ja",
                                    "color": "green",
                                    "action": "continue"
                                  },
                                  {
                                    "id": "nein",
                                    "label": "Nein",
                                    "color": "red",
                                    "action": "show_text",
                                    "response_text": "Was wäre das Schlimmste, das in 10 Minuten passieren kann?"
                                  }
                                ]
                              }
                            ],
                            "conditions": {},
                            "variable_fallbacks": {
                              "first_name": "Sie"
                            },
                            "linked_custom_field_ids": [],
                            "is_default": true,
                            "sort_order": 1,
                            "created_at": "2026-09-02T08:00:00.000Z",
                            "updated_at": "2026-10-10T14:30:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Gesprächsleitfadens",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name des Leitfadens"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kurzbeschreibung"
                          },
                          "call_type": {
                            "type": "string",
                            "description": "Art des Gesprächs, z. B. standard, qualification, demo, closing, checkin"
                          },
                          "for_statuses": {
                            "type": "array",
                            "description": "Lead-Status, bei denen die App den Leitfaden vorschlägt, z. B. open, contacted",
                            "items": {
                              "type": "string"
                            }
                          },
                          "target_persona": {
                            "type": "string",
                            "description": "Für wen: universal (alle), decision_maker (Entscheider) oder gatekeeper (Vorzimmer)",
                            "enum": [
                              "universal",
                              "decision_maker",
                              "gatekeeper"
                            ]
                          },
                          "content": {
                            "type": "string",
                            "description": "Text des Leitfadens. Platzhalter wie {{first_name}} ersetzt die App beim Anruf, {{section:Name}} sind Abschnitte, {{decision:id}} die Entscheidungsknöpfe aus inline_decisions"
                          },
                          "questions": {
                            "type": "array",
                            "description": "Fragen zur Qualifizierung während des Gesprächs: id, question, type (text, number, select, checkbox), required, options",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "inline_decisions": {
                            "type": "array",
                            "description": "Entscheidungsknöpfe im Text: id, question, options (id, label, color, action show_text, switch_script oder continue, response_text, target_script_id)",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            }
                          },
                          "conditions": {
                            "type": "object",
                            "description": "Bedingungen, wann die App den Leitfaden vorschlägt (z. B. follow_up_reason, last_call_persona). Leer = keine",
                            "additionalProperties": true
                          },
                          "variable_fallbacks": {
                            "type": "object",
                            "description": "Ersatztexte je Platzhalter, wenn der Lead den Wert nicht hat, z. B. first_name: Sie",
                            "additionalProperties": true
                          },
                          "linked_custom_field_ids": {
                            "type": "array",
                            "description": "Custom Fields, die die App im Leitfaden zur Qualifizierung zeigt (GET /v1/custom-fields)",
                            "items": {
                              "type": "string",
                              "format": "uuid"
                            }
                          },
                          "is_default": {
                            "type": "boolean",
                            "description": "Standard-Leitfaden"
                          },
                          "sort_order": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Position in der Liste der App"
                          },
                          "created_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der Anlage",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der letzten Änderung",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "2f3e4d5c-6b7a-4891-8a0b-1c2d3e4f5a6b",
                          "name": "Entscheider Skript",
                          "description": "Nachdem man zum Entscheider durchgestellt wurde",
                          "call_type": "standard",
                          "for_statuses": [
                            "open",
                            "contacted",
                            "not_reached",
                            "interested"
                          ],
                          "target_persona": "decision_maker",
                          "content": "Hallo {{anrede}} {{last_name}},\n\nhier ist {{my_first_name}} von Muster GmbH.\n\n{{section:Pitch}}\nWir haben Ihnen neulich eine persönliche Videonachricht gesendet. Hatten Sie schon die Möglichkeit, sie anzuschauen?\n\n{{decision:interesse}}",
                          "questions": [
                            {
                              "id": "q1",
                              "question": "Wie viele Vertriebler im Team?",
                              "type": "number",
                              "required": false
                            }
                          ],
                          "inline_decisions": [
                            {
                              "id": "interesse",
                              "question": "Hat der Kontakt Interesse?",
                              "options": [
                                {
                                  "id": "ja",
                                  "label": "Ja",
                                  "color": "green",
                                  "action": "continue"
                                },
                                {
                                  "id": "nein",
                                  "label": "Nein",
                                  "color": "red",
                                  "action": "show_text",
                                  "response_text": "Was wäre das Schlimmste, das in 10 Minuten passieren kann?"
                                }
                              ]
                            }
                          ],
                          "conditions": {},
                          "variable_fallbacks": {
                            "first_name": "Sie"
                          },
                          "linked_custom_field_ids": [],
                          "is_default": true,
                          "sort_order": 1,
                          "created_at": "2026-09-02T08:00:00.000Z",
                          "updated_at": "2026-10-10T14:30:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "crm",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/call-scripts/{id}": {
      "get": {
        "operationId": "getCallScript",
        "tags": [
          "CRM"
        ],
        "summary": "Gesprächsleitfaden lesen",
        "description": "Ein Gesprächsleitfaden mit Text, Fragen und Entscheidungsknöpfen, wie unter GET /v1/call-scripts. Ein in der App gelöschter Leitfaden ergibt 404. Liest nur, kostet nichts.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** `crm` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Gesprächsleitfadens",
              "format": "uuid"
            },
            "description": "ID des Gesprächsleitfadens"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "2f3e4d5c-6b7a-4891-8a0b-1c2d3e4f5a6b",
                          "name": "Entscheider Skript",
                          "description": "Nachdem man zum Entscheider durchgestellt wurde",
                          "call_type": "standard",
                          "for_statuses": [
                            "open",
                            "contacted",
                            "not_reached",
                            "interested"
                          ],
                          "target_persona": "decision_maker",
                          "content": "Hallo {{anrede}} {{last_name}},\n\nhier ist {{my_first_name}} von Muster GmbH.\n\n{{section:Pitch}}\nWir haben Ihnen neulich eine persönliche Videonachricht gesendet. Hatten Sie schon die Möglichkeit, sie anzuschauen?\n\n{{decision:interesse}}",
                          "questions": [
                            {
                              "id": "q1",
                              "question": "Wie viele Vertriebler im Team?",
                              "type": "number",
                              "required": false
                            }
                          ],
                          "inline_decisions": [
                            {
                              "id": "interesse",
                              "question": "Hat der Kontakt Interesse?",
                              "options": [
                                {
                                  "id": "ja",
                                  "label": "Ja",
                                  "color": "green",
                                  "action": "continue"
                                },
                                {
                                  "id": "nein",
                                  "label": "Nein",
                                  "color": "red",
                                  "action": "show_text",
                                  "response_text": "Was wäre das Schlimmste, das in 10 Minuten passieren kann?"
                                }
                              ]
                            }
                          ],
                          "conditions": {},
                          "variable_fallbacks": {
                            "first_name": "Sie"
                          },
                          "linked_custom_field_ids": [],
                          "is_default": true,
                          "sort_order": 1,
                          "created_at": "2026-09-02T08:00:00.000Z",
                          "updated_at": "2026-10-10T14:30:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Gesprächsleitfadens",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name des Leitfadens"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kurzbeschreibung"
                        },
                        "call_type": {
                          "type": "string",
                          "description": "Art des Gesprächs, z. B. standard, qualification, demo, closing, checkin"
                        },
                        "for_statuses": {
                          "type": "array",
                          "description": "Lead-Status, bei denen die App den Leitfaden vorschlägt, z. B. open, contacted",
                          "items": {
                            "type": "string"
                          }
                        },
                        "target_persona": {
                          "type": "string",
                          "description": "Für wen: universal (alle), decision_maker (Entscheider) oder gatekeeper (Vorzimmer)",
                          "enum": [
                            "universal",
                            "decision_maker",
                            "gatekeeper"
                          ]
                        },
                        "content": {
                          "type": "string",
                          "description": "Text des Leitfadens. Platzhalter wie {{first_name}} ersetzt die App beim Anruf, {{section:Name}} sind Abschnitte, {{decision:id}} die Entscheidungsknöpfe aus inline_decisions"
                        },
                        "questions": {
                          "type": "array",
                          "description": "Fragen zur Qualifizierung während des Gesprächs: id, question, type (text, number, select, checkbox), required, options",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "inline_decisions": {
                          "type": "array",
                          "description": "Entscheidungsknöpfe im Text: id, question, options (id, label, color, action show_text, switch_script oder continue, response_text, target_script_id)",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "conditions": {
                          "type": "object",
                          "description": "Bedingungen, wann die App den Leitfaden vorschlägt (z. B. follow_up_reason, last_call_persona). Leer = keine",
                          "additionalProperties": true
                        },
                        "variable_fallbacks": {
                          "type": "object",
                          "description": "Ersatztexte je Platzhalter, wenn der Lead den Wert nicht hat, z. B. first_name: Sie",
                          "additionalProperties": true
                        },
                        "linked_custom_field_ids": {
                          "type": "array",
                          "description": "Custom Fields, die die App im Leitfaden zur Qualifizierung zeigt (GET /v1/custom-fields)",
                          "items": {
                            "type": "string",
                            "format": "uuid"
                          }
                        },
                        "is_default": {
                          "type": "boolean",
                          "description": "Standard-Leitfaden"
                        },
                        "sort_order": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Position in der Liste der App"
                        },
                        "created_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "2f3e4d5c-6b7a-4891-8a0b-1c2d3e4f5a6b",
                        "name": "Entscheider Skript",
                        "description": "Nachdem man zum Entscheider durchgestellt wurde",
                        "call_type": "standard",
                        "for_statuses": [
                          "open",
                          "contacted",
                          "not_reached",
                          "interested"
                        ],
                        "target_persona": "decision_maker",
                        "content": "Hallo {{anrede}} {{last_name}},\n\nhier ist {{my_first_name}} von Muster GmbH.\n\n{{section:Pitch}}\nWir haben Ihnen neulich eine persönliche Videonachricht gesendet. Hatten Sie schon die Möglichkeit, sie anzuschauen?\n\n{{decision:interesse}}",
                        "questions": [
                          {
                            "id": "q1",
                            "question": "Wie viele Vertriebler im Team?",
                            "type": "number",
                            "required": false
                          }
                        ],
                        "inline_decisions": [
                          {
                            "id": "interesse",
                            "question": "Hat der Kontakt Interesse?",
                            "options": [
                              {
                                "id": "ja",
                                "label": "Ja",
                                "color": "green",
                                "action": "continue"
                              },
                              {
                                "id": "nein",
                                "label": "Nein",
                                "color": "red",
                                "action": "show_text",
                                "response_text": "Was wäre das Schlimmste, das in 10 Minuten passieren kann?"
                              }
                            ]
                          }
                        ],
                        "conditions": {},
                        "variable_fallbacks": {
                          "first_name": "Sie"
                        },
                        "linked_custom_field_ids": [],
                        "is_default": true,
                        "sort_order": 1,
                        "created_at": "2026-09-02T08:00:00.000Z",
                        "updated_at": "2026-10-10T14:30:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "crm",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/phone-numbers": {
      "get": {
        "operationId": "listPhoneNumbers",
        "tags": [
          "CRM"
        ],
        "summary": "Eigene Rufnummern auflisten",
        "description": "Die Rufnummern des Kontos, wie sie unter Einstellungen, Telefonie (Call-Flow) stehen: Nummer, Land, Status und das Team-Mitglied, dem sie zugewiesen ist. Gelöschte Nummern fehlen wie in der App, neueste zuerst.\n\n`country` leitet die API aus der Ländervorwahl ab (DE, AT, CH), bei anderen Vorwahlen ist es null. Twilio-Kennungen und Kosten gibt die API nicht heraus.\n\nRecht wie in der App: Die Seite ist Inhabern und Admins vorbehalten. Ein Mitglied sieht in der App nur die eigene zugewiesene Nummer im Telefon und bekommt hier 403. Kaufen, zuweisen und freigeben geht nur in der App. Liest nur, kostet nichts.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** nur Leitung (die Person, die den Key erzeugt hat, muss Inhaber oder Admin sein, wie in der App)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
                            "phone_number": "+4930123456789",
                            "country": "DE",
                            "status": "active",
                            "assigned_user_id": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                            "purchased_at": "2026-09-15T10:20:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Rufnummer",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "phone_number": {
                            "type": "string",
                            "description": "Rufnummer im Format E.164, z. B. +4930123456789"
                          },
                          "country": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Land aus der Ländervorwahl (DE, AT, CH), sonst null",
                            "enum": [
                              "DE",
                              "AT",
                              "CH",
                              null
                            ]
                          },
                          "status": {
                            "type": "string",
                            "description": "active (bereit für Anrufe) oder pending (wartet auf die Dokumentenprüfung)",
                            "enum": [
                              "active",
                              "pending"
                            ]
                          },
                          "assigned_user_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Team-Mitglied, dem die Nummer zugewiesen ist (GET /v1/team). null = niemandem",
                            "format": "uuid"
                          },
                          "purchased_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der Freischaltung",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d",
                          "phone_number": "+4930123456789",
                          "country": "DE",
                          "status": "active",
                          "assigned_user_id": "8e7d6c5b-4a39-4281-9f0e-1d2c3b4a5f60",
                          "purchased_at": "2026-09-15T10:20:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "leitung",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/leads/{id}/contacts": {
      "get": {
        "operationId": "listLeadContacts",
        "tags": [
          "CRM"
        ],
        "summary": "Kontaktpersonen eines Leads",
        "description": "Weitere Ansprechpartner am Lead, wie im Lead-Panel der App: der primäre zuerst, dann nach Anlage. Die Person des Leads selbst steht in GET /v1/leads/{id}.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "4d5e6f70-8192-4a3b-9c4d-5e6f7a8b9c0d",
                            "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                            "first_name": "Erika",
                            "last_name": "Beispiel",
                            "email": "erika.beispiel@beispiel.de",
                            "phone": "+49 30 1234567",
                            "linkedin_url": "https://www.linkedin.com/in/erika-beispiel",
                            "title": "Assistenz der Geschäftsführung",
                            "is_primary": true,
                            "created_at": "2026-10-18T09:12:00.000Z",
                            "updated_at": "2026-10-18T09:12:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Kontaktperson",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "lead_id": {
                            "type": "string",
                            "description": "Lead, zu dem die Kontaktperson gehört",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "first_name": {
                            "type": "string",
                            "description": "Vorname (Pflicht, wie in der App)",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "last_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nachname der Kontaktperson",
                            "maxLength": 200
                          },
                          "email": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "E-Mail-Adresse der Kontaktperson, wird klein geschrieben gespeichert. Keine Dublettenprüfung, wie in der App",
                            "format": "email",
                            "maxLength": 320
                          },
                          "phone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Wird so gespeichert, wie übergeben (wie in der App)",
                            "maxLength": 50
                          },
                          "linkedin_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LinkedIn-Profil-URL",
                            "format": "uri",
                            "maxLength": 2048
                          },
                          "title": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Position, z. B. Assistenz der Geschäftsführung",
                            "maxLength": 300
                          },
                          "is_primary": {
                            "type": "boolean",
                            "description": "Primärer Kontakt des Leads. Der erste Kontakt wird es automatisch.",
                            "readOnly": true
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Angelegt am",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "Zuletzt geändert am",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "4d5e6f70-8192-4a3b-9c4d-5e6f7a8b9c0d",
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "first_name": "Erika",
                          "last_name": "Beispiel",
                          "email": "erika.beispiel@beispiel.de",
                          "phone": "+49 30 1234567",
                          "linkedin_url": "https://www.linkedin.com/in/erika-beispiel",
                          "title": "Assistenz der Geschäftsführung",
                          "is_primary": true,
                          "created_at": "2026-10-18T09:12:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      },
      "post": {
        "operationId": "createLeadContact",
        "tags": [
          "CRM"
        ],
        "summary": "Kontaktperson am Lead anlegen",
        "description": "Legt einen weiteren Ansprechpartner am Lead an, wie „Weiteren Kontakt hinzufügen“ im Lead-Panel, und schreibt den Eintrag „Neuer Kontakt hinzugefügt“ in den Verlauf. Nur der Vorname ist Pflicht. Eine Dublettenprüfung gibt es dabei nicht, auch nicht in der App.\n\n**Wie in der App wird der erste Kontakt eines Leads automatisch primär.** Die Leads-Tabelle der App zeigt dann dessen Name und E-Mail statt der Angaben des Leads. LinkedIn-Outreach, Landingpages und Videos nutzen weiter die Felder des Leads.\n\n**Berechtigung:** `write:crm`\n\n**Recht in dealsky:** `crm.leads.write` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "first_name": {
                    "type": "string",
                    "description": "Vorname (Pflicht, wie in der App)",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "last_name": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Nachname der Kontaktperson",
                    "maxLength": 200
                  },
                  "email": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "E-Mail-Adresse der Kontaktperson, wird klein geschrieben gespeichert. Keine Dublettenprüfung, wie in der App",
                    "format": "email",
                    "maxLength": 320
                  },
                  "phone": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Wird so gespeichert, wie übergeben (wie in der App)",
                    "maxLength": 50
                  },
                  "linkedin_url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "LinkedIn-Profil-URL",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "title": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Position, z. B. Assistenz der Geschäftsführung",
                    "maxLength": 300
                  }
                },
                "required": [
                  "first_name"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "first_name": "Erika",
                    "last_name": "Beispiel",
                    "email": "erika.beispiel@beispiel.de",
                    "phone": "+49 30 1234567",
                    "linkedin_url": "https://www.linkedin.com/in/erika-beispiel",
                    "title": "Assistenz der Geschäftsführung"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "4d5e6f70-8192-4a3b-9c4d-5e6f7a8b9c0d",
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "first_name": "Erika",
                          "last_name": "Beispiel",
                          "email": "erika.beispiel@beispiel.de",
                          "phone": "+49 30 1234567",
                          "linkedin_url": "https://www.linkedin.com/in/erika-beispiel",
                          "title": "Assistenz der Geschäftsführung",
                          "is_primary": true,
                          "created_at": "2026-10-18T09:12:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Kontaktperson",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "lead_id": {
                          "type": "string",
                          "description": "Lead, zu dem die Kontaktperson gehört",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "first_name": {
                          "type": "string",
                          "description": "Vorname (Pflicht, wie in der App)",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "last_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nachname der Kontaktperson",
                          "maxLength": 200
                        },
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "E-Mail-Adresse der Kontaktperson, wird klein geschrieben gespeichert. Keine Dublettenprüfung, wie in der App",
                          "format": "email",
                          "maxLength": 320
                        },
                        "phone": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Wird so gespeichert, wie übergeben (wie in der App)",
                          "maxLength": 50
                        },
                        "linkedin_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Profil-URL",
                          "format": "uri",
                          "maxLength": 2048
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Position, z. B. Assistenz der Geschäftsführung",
                          "maxLength": 300
                        },
                        "is_primary": {
                          "type": "boolean",
                          "description": "Primärer Kontakt des Leads. Der erste Kontakt wird es automatisch.",
                          "readOnly": true
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Angelegt am",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zuletzt geändert am",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "4d5e6f70-8192-4a3b-9c4d-5e6f7a8b9c0d",
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "first_name": "Erika",
                        "last_name": "Beispiel",
                        "email": "erika.beispiel@beispiel.de",
                        "phone": "+49 30 1234567",
                        "linkedin_url": "https://www.linkedin.com/in/erika-beispiel",
                        "title": "Assistenz der Geschäftsführung",
                        "is_primary": true,
                        "created_at": "2026-10-18T09:12:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:crm",
        "x-dealsky-permission": "crm.leads.write",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/account": {
      "get": {
        "operationId": "getAccount",
        "tags": [
          "Konto"
        ],
        "summary": "Mandant, Tarif und Credit-Stand",
        "description": "Liest Mandant, Tarif, laufendes Abo und Credit-Stand. Kostet nichts. `credits.effective` ist, was jetzt ausgegeben werden kann: verfügbar minus vorgemerkt plus Bonus, wie die Credit-Anzeige der App und die Abbuchung (Bonus wird zuerst verbraucht). Ab 999999 gilt das Konto als unbegrenzt (`credits.unlimited`). Zahlungsmittel, Rechnungen und Vertragsdetails gibt die API nicht heraus. Wie die Abrechnung in der App nur für Inhaber und Admins.\n\n**Berechtigung:** `read:account`\n\n**Recht in dealsky:** nur Leitung (die Person, die den Key erzeugt hat, muss Inhaber oder Admin sein, wie in der App)\n\n**Wirkung:** Liest nur.",
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "tenant": {
                            "id": "3c9d2e1f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                            "name": "Beispiel GmbH"
                          },
                          "plan_tier": "scale",
                          "subscription": {
                            "plan_tier": "scale",
                            "status": "active",
                            "current_period_end": "2026-11-01T00:00:00.000Z",
                            "cancel_at_period_end": false,
                            "is_paused": false
                          },
                          "credits": {
                            "available": 4200,
                            "reserved": 300,
                            "bonus": 500,
                            "effective": 4400,
                            "unlimited": false,
                            "used_this_period": 1800,
                            "plan_package": 6000,
                            "period_end": "2026-11-01T00:00:00.000Z"
                          }
                        }
                      ],
                      "properties": {
                        "tenant": {
                          "type": "object",
                          "description": "Mandant des Keys",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "ID des Mandanten, zu dem der API-Key gehört",
                              "format": "uuid"
                            },
                            "name": {
                              "type": "string",
                              "description": "Firmenname des Mandanten, leer, wenn keiner hinterlegt ist"
                            }
                          },
                          "additionalProperties": false
                        },
                        "plan_tier": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Tarif wie in der App: aus dem laufenden Abo, sonst aus dem Credit-Konto",
                          "enum": [
                            "business",
                            "growth",
                            "scale",
                            "enterprise",
                            null
                          ]
                        },
                        "subscription": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Laufendes Abo, null ohne Abo",
                          "properties": {
                            "plan_tier": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Tarif laut Abo (subscriptions.plan_tier), null, wenn das Abo keinen nennt"
                            },
                            "status": {
                              "type": "string",
                              "description": "active, past_due (Zahlung offen), unpaid, scheduled (startet später)",
                              "enum": [
                                "active",
                                "past_due",
                                "unpaid",
                                "scheduled"
                              ]
                            },
                            "current_period_end": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ende des laufenden Abrechnungszeitraums",
                              "format": "date-time"
                            },
                            "cancel_at_period_end": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "Gekündigt zum Ende des Zeitraums"
                            },
                            "is_paused": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "Abo ist pausiert. null, wenn das Abo dazu nichts speichert"
                            }
                          },
                          "additionalProperties": false
                        },
                        "credits": {
                          "type": "object",
                          "description": "Credit-Stand. effective ist, was jetzt ausgegeben werden kann",
                          "properties": {
                            "available": {
                              "type": "integer",
                              "description": "Freies Plan-Guthaben"
                            },
                            "reserved": {
                              "type": "integer",
                              "description": "Vorgemerkt für laufende Aufträge (z. B. Videos), noch nicht abgebucht"
                            },
                            "bonus": {
                              "type": "integer",
                              "description": "Bonus-Credits, verfallen nie und werden zuerst verbraucht"
                            },
                            "effective": {
                              "type": "integer",
                              "description": "Jetzt ausgebbar: available minus reserved plus bonus, nie unter 0"
                            },
                            "unlimited": {
                              "type": "boolean",
                              "description": "Unbegrenztes Konto (ab 999999 Credits)"
                            },
                            "used_this_period": {
                              "type": "integer",
                              "description": "Im laufenden Zeitraum aus dem Plan-Guthaben verbraucht"
                            },
                            "plan_package": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Monatliches Credit-Paket des Tarifs"
                            },
                            "period_end": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ende des Credit-Zeitraums, danach wird das Plan-Guthaben neu gesetzt. null ohne Credit-Konto",
                              "format": "date-time"
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "tenant": {
                          "id": "3c9d2e1f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                          "name": "Beispiel GmbH"
                        },
                        "plan_tier": "scale",
                        "subscription": {
                          "plan_tier": "scale",
                          "status": "active",
                          "current_period_end": "2026-11-01T00:00:00.000Z",
                          "cancel_at_period_end": false,
                          "is_paused": false
                        },
                        "credits": {
                          "available": 4200,
                          "reserved": 300,
                          "bonus": 500,
                          "effective": 4400,
                          "unlimited": false,
                          "used_this_period": 1800,
                          "plan_package": 6000,
                          "period_end": "2026-11-01T00:00:00.000Z"
                        }
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:account",
        "x-dealsky-permission": "leitung",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/account/credit-transactions": {
      "get": {
        "operationId": "listCreditTransactions",
        "tags": [
          "Konto"
        ],
        "summary": "Credit-Verlauf",
        "description": "Gutschriften und Verbrauch, neueste zuerst, wie der Credit-Verlauf der App (interne Merkposten sind ausgeblendet). Kostet nichts. `amount` ist positiv bei Gutschriften und negativ bei Verbrauch. Wie in der App nur für Inhaber und Admins.\n\n**Berechtigung:** `read:account`\n\n**Recht in dealsky:** nur Leitung (die Person, die den Key erzeugt hat, muss Inhaber oder Admin sein, wie in der App)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Eine oder mehrere Buchungsarten, kommagetrennt, z. B. landing_page,ai_opener",
              "items": {
                "type": "string",
                "maxLength": 100
              },
              "maxItems": 20
            },
            "description": "Eine oder mehrere Buchungsarten, kommagetrennt, z. B. landing_page,ai_opener",
            "style": "form",
            "explode": false
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Buchungen ab diesem Zeitpunkt",
              "format": "date-time"
            },
            "description": "Nur Buchungen ab diesem Zeitpunkt"
          },
          {
            "name": "created_before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Buchungen vor diesem Zeitpunkt",
              "format": "date-time"
            },
            "description": "Nur Buchungen vor diesem Zeitpunkt"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Buchung",
                            "format": "uuid"
                          },
                          "amount": {
                            "type": "integer",
                            "description": "Positiv: Gutschrift, negativ: Verbrauch"
                          },
                          "type": {
                            "type": "string",
                            "description": "Art der Buchung, z. B. monthly_allocation, landing_page, admin_video_personalization, ai_opener"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Buchungstext wie im Credit-Verlauf der App, ohne das interne Bonus/Regular-Detail. null ohne Text"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt der Buchung",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Verbrauch für Landingpages seit Monatsbeginn",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "7d1e2f3a-4b5c-4d6e-8f9a-0b1c2d3e4f5a",
                          "amount": -5,
                          "type": "landing_page",
                          "description": "Landingpage für Max Mustermann",
                          "created_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Letzte Buchungen",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "7d1e2f3a-4b5c-4d6e-8f9a-0b1c2d3e4f5a",
                          "amount": -5,
                          "type": "landing_page",
                          "description": "Landingpage für Max Mustermann",
                          "created_at": "2026-10-18T09:12:00.000Z"
                        },
                        {
                          "id": "6c0d1e2f-3a4b-4c5d-9e8f-7a6b5c4d3e2f",
                          "amount": 6000,
                          "type": "monthly_allocation",
                          "description": "Monatliches Guthaben Oktober",
                          "created_at": "2026-10-01T00:00:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:account",
        "x-dealsky-permission": "leitung",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/team": {
      "get": {
        "operationId": "listTeamMembers",
        "tags": [
          "Team"
        ],
        "summary": "Team-Mitglieder",
        "description": "Alle Personen im Konto mit Rolle, sortiert nach Name. Die `id` ist der Wert für `assigned_user_id` an Leads. Wer Leads sieht, sieht wie in der App die Kollegen im Feld „Zuständig“. E-Mail und letzter Login kommen nur mit, wenn die Person, die den Key erzeugt hat, das Recht `settings.team` (Team-Verwaltung) hat, wie auf der Team-Seite der App. Offene Einladungen, Rechte und Konto-Zuweisungen gibt die API nicht heraus.\n\n**Berechtigung:** `read:team`\n\n**Recht in dealsky:** `crm.leads.read` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Person, z. B. für assigned_user_id an Leads",
                            "format": "uuid"
                          },
                          "full_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Anzeigename aus dem Profil, null, wenn nicht gepflegt"
                          },
                          "first_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vorname aus dem Profil, null, wenn nicht gepflegt"
                          },
                          "last_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nachname aus dem Profil, null, wenn nicht gepflegt"
                          },
                          "avatar_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "URL des Profilbilds, null ohne Bild"
                          },
                          "role": {
                            "type": "string",
                            "description": "tenant_owner: Inhaber, tenant_admin: Admin, tenant_user: Mitglied mit einzeln vergebenen Rechten",
                            "enum": [
                              "tenant_owner",
                              "tenant_admin",
                              "tenant_user"
                            ]
                          },
                          "created_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Im Team seit",
                            "format": "date-time"
                          },
                          "email": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nur wenn die Person, die den Key erzeugt hat, das Recht settings.team (Team-Verwaltung) hat. Sonst fehlt das Feld.",
                            "format": "email",
                            "maxLength": 320
                          },
                          "last_sign_in_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzter Login. Nur mit settings.team, sonst fehlt das Feld.",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Ohne settings.team",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "a3a3a3a3-a3a3-4a3a-8a3a-a3a3a3a3a3a3",
                          "full_name": "Anna Beispiel",
                          "first_name": "Anna",
                          "last_name": "Beispiel",
                          "avatar_url": "https://imagedelivery.net/beispiel/avatar/public",
                          "role": "tenant_admin",
                          "created_at": "2026-03-02T10:00:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Mit settings.team",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "a3a3a3a3-a3a3-4a3a-8a3a-a3a3a3a3a3a3",
                          "full_name": "Anna Beispiel",
                          "first_name": "Anna",
                          "last_name": "Beispiel",
                          "avatar_url": "https://imagedelivery.net/beispiel/avatar/public",
                          "role": "tenant_admin",
                          "created_at": "2026-03-02T10:00:00.000Z",
                          "email": "anna@beispiel.de",
                          "last_sign_in_at": "2026-10-17T16:40:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:team",
        "x-dealsky-permission": "crm.leads.read",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/campaigns": {
      "get": {
        "operationId": "listCampaigns",
        "tags": [
          "Kampagnen"
        ],
        "summary": "Kampagnen auflisten",
        "description": "Neueste zuerst, wie die Kampagnenliste der App. `progress` zählt die Leads in der Sequenz in drei Gruppen (offen, mit Ergebnis, abgebrochen) und rechnet den Fortschritt wie die Liste. Eine Lead-Anzahl aus der Kampagnenzeile gibt es bewusst nicht (sie ist dort oft veraltet); die gezählte steht in GET /v1/campaigns/{id}. Sichtbar sind nur Kampagnen auf LinkedIn-Konten, auf die die Person hinter dem Key Zugriff hat.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.campaigns.view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Ein oder mehrere Status, kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "draft",
                  "active",
                  "sent",
                  "paused",
                  "completed",
                  "stopped",
                  "archived"
                ]
              }
            },
            "description": "Ein oder mehrere Status, kommagetrennt",
            "style": "form",
            "explode": false
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Teil des Namens (Groß/Klein egal)",
              "maxLength": 200
            },
            "description": "Teil des Namens (Groß/Klein egal)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Kampagne",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name der Kampagne"
                          },
                          "status": {
                            "type": "string",
                            "description": "Status der Kampagne, z. B. draft (Entwurf), active (läuft), paused, completed, stopped, archived",
                            "enum": [
                              "draft",
                              "active",
                              "sent",
                              "paused",
                              "completed",
                              "stopped",
                              "archived"
                            ]
                          },
                          "orchestration_status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Stand der Ausführung: draft, scheduled, running, paused, completed, failed, stopped"
                          },
                          "channels": {
                            "type": "array",
                            "description": "Kanäle, z. B. linkedin",
                            "items": {
                              "type": "string"
                            }
                          },
                          "campaign_type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Art aus den Schritten der Sequenz: connect_only (Vernetzen), message_only (Nachrichten an Kontakte), connect_and_message",
                            "enum": [
                              "connect_only",
                              "message_only",
                              "connect_and_message",
                              null
                            ]
                          },
                          "linkedin_account": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Verknüpftes LinkedIn-Konto (nur sichtbar, wenn der Key-Ersteller Zugriff auf das Konto hat)",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "ID des LinkedIn-Kontos (siehe /v1/linkedin/accounts)",
                                "format": "uuid"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Anzeigename des Kontos, null ohne Namen"
                              },
                              "connection_status": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "connected, pending_verification, broken, disconnected, error"
                              }
                            },
                            "additionalProperties": false
                          },
                          "sequence_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Verknüpfte LinkedIn-Sequenz, null ohne Sequenz (z. B. Entwurf)",
                            "format": "uuid"
                          },
                          "list_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Lead-Liste, aus der die Kampagne befüllt wurde",
                            "format": "uuid"
                          },
                          "progress": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Fortschritt wie die Kampagnenliste der App. null, wenn die Zählung gerade nicht verfügbar ist.",
                            "properties": {
                              "total": {
                                "type": "integer",
                                "description": "Eingeschriebene Leads (Zeilen der Sequenz)"
                              },
                              "open": {
                                "type": "integer",
                                "description": "Noch in Arbeit: pending, active, in_progress, waiting_for_connection, paused, paused_no_credits"
                              },
                              "result": {
                                "type": "integer",
                                "description": "Mit Ergebnis durch: completed, replied, booked"
                              },
                              "aborted": {
                                "type": "integer",
                                "description": "Ohne Ergebnis raus: failed, excluded, stopped"
                              },
                              "stopped": {
                                "type": "integer",
                                "description": "Absichtlich gestoppt oder ausgeschlossen (Teil von aborted)"
                              },
                              "failed": {
                                "type": "integer",
                                "description": "Echte Fehlschläge (Teil von aborted)"
                              },
                              "percent": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Durch, egal wie, in Prozent. 100 nur, wenn niemand mehr offen ist. null ohne Leads."
                              }
                            },
                            "additionalProperties": false
                          },
                          "start_date": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Startdatum der Kampagne, null ohne Angabe",
                            "format": "date-time"
                          },
                          "end_date": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Enddatum der Kampagne, null ohne Angabe",
                            "format": "date-time"
                          },
                          "created_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Angelegt am",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zuletzt geändert am",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Laufende Kampagnen",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "c7a1e2d3-4b5c-4d6e-8f70-1a2b3c4d5e6f",
                          "name": "Geschäftsführer Logistik NRW",
                          "status": "active",
                          "orchestration_status": "running",
                          "channels": [
                            "linkedin"
                          ],
                          "campaign_type": "connect_and_message",
                          "linkedin_account": {
                            "id": "acc4e2d1-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                            "name": "Anna Beispiel",
                            "connection_status": "connected"
                          },
                          "sequence_id": "5e9f0a1b-2c3d-4e5f-8a6b-7c8d9e0f1a2b",
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "progress": {
                            "total": 240,
                            "open": 150,
                            "result": 72,
                            "aborted": 18,
                            "stopped": 15,
                            "failed": 3,
                            "percent": 37
                          },
                          "start_date": "2026-10-01T08:00:00.000Z",
                          "end_date": null,
                          "created_at": "2026-09-30T14:12:00.000Z",
                          "updated_at": "2026-10-18T09:00:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.campaigns.view",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/campaigns/{id}": {
      "get": {
        "operationId": "getCampaign",
        "tags": [
          "Kampagnen"
        ],
        "summary": "Eine Kampagne abrufen",
        "description": "Stammdaten, Status, verknüpftes LinkedIn-Konto, Sequenz mit Zeitplan und Tageslimits, Fortschritt und die gezählte Lead-Anzahl (ohne archivierte Leads, bei beendeten Kampagnen mit). Zeitplan und Limits stammen aus der Sequenz. Bei einem Entwurf stehen die Tageslimits noch im Aufbau der Kampagne (der Start überträgt sie in die Sequenz), dann gelten diese. Fehlt ein Wert, steht der Standard, den die App anzeigt und mit dem sie arbeitet.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.campaigns.view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Kampagne",
              "format": "uuid"
            },
            "description": "ID der Kampagne"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Kampagne",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Kampagne"
                        },
                        "status": {
                          "type": "string",
                          "description": "Status der Kampagne, z. B. draft (Entwurf), active (läuft), paused, completed, stopped, archived",
                          "enum": [
                            "draft",
                            "active",
                            "sent",
                            "paused",
                            "completed",
                            "stopped",
                            "archived"
                          ]
                        },
                        "orchestration_status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stand der Ausführung: draft, scheduled, running, paused, completed, failed, stopped"
                        },
                        "channels": {
                          "type": "array",
                          "description": "Kanäle, z. B. linkedin",
                          "items": {
                            "type": "string"
                          }
                        },
                        "campaign_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Art aus den Schritten der Sequenz: connect_only (Vernetzen), message_only (Nachrichten an Kontakte), connect_and_message",
                          "enum": [
                            "connect_only",
                            "message_only",
                            "connect_and_message",
                            null
                          ]
                        },
                        "linkedin_account": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Verknüpftes LinkedIn-Konto (nur sichtbar, wenn der Key-Ersteller Zugriff auf das Konto hat)",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "ID des LinkedIn-Kontos (siehe /v1/linkedin/accounts)",
                              "format": "uuid"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Anzeigename des Kontos, null ohne Namen"
                            },
                            "connection_status": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "connected, pending_verification, broken, disconnected, error"
                            }
                          },
                          "additionalProperties": false
                        },
                        "sequence_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Verknüpfte LinkedIn-Sequenz, null ohne Sequenz (z. B. Entwurf)",
                          "format": "uuid"
                        },
                        "list_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Lead-Liste, aus der die Kampagne befüllt wurde",
                          "format": "uuid"
                        },
                        "progress": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Fortschritt wie die Kampagnenliste der App. null, wenn die Zählung gerade nicht verfügbar ist.",
                          "properties": {
                            "total": {
                              "type": "integer",
                              "description": "Eingeschriebene Leads (Zeilen der Sequenz)"
                            },
                            "open": {
                              "type": "integer",
                              "description": "Noch in Arbeit: pending, active, in_progress, waiting_for_connection, paused, paused_no_credits"
                            },
                            "result": {
                              "type": "integer",
                              "description": "Mit Ergebnis durch: completed, replied, booked"
                            },
                            "aborted": {
                              "type": "integer",
                              "description": "Ohne Ergebnis raus: failed, excluded, stopped"
                            },
                            "stopped": {
                              "type": "integer",
                              "description": "Absichtlich gestoppt oder ausgeschlossen (Teil von aborted)"
                            },
                            "failed": {
                              "type": "integer",
                              "description": "Echte Fehlschläge (Teil von aborted)"
                            },
                            "percent": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Durch, egal wie, in Prozent. 100 nur, wenn niemand mehr offen ist. null ohne Leads."
                            }
                          },
                          "additionalProperties": false
                        },
                        "start_date": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Startdatum der Kampagne, null ohne Angabe",
                          "format": "date-time"
                        },
                        "end_date": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Enddatum der Kampagne, null ohne Angabe",
                          "format": "date-time"
                        },
                        "created_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Angelegt am",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zuletzt geändert am",
                          "format": "date-time"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Beschreibung der Kampagne, null ohne Text"
                        },
                        "leads_count": {
                          "type": "integer",
                          "description": "Leads mit dieser Kampagne (gezählt, ohne archivierte; bei beendeten Kampagnen mit archivierten)"
                        },
                        "sequence": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Verknüpfte LinkedIn-Sequenz, null ohne Sequenz",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "ID der Sequenz",
                              "format": "uuid"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Name der Sequenz, null ohne Namen"
                            },
                            "category": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "connection (Vernetzungskampagne) oder outreach"
                            },
                            "status": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Status der Sequenz, z. B. active, paused, draft"
                            },
                            "orchestration_status": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "running, paused, stopped, completed. Nur running versendet."
                            }
                          },
                          "additionalProperties": false
                        },
                        "schedule": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Zeitplan der Sequenz. Fehlende Werte zeigen den Standard der App.",
                          "properties": {
                            "timezone": {
                              "type": "string",
                              "description": "Zeitzone des Zeitplans, Standard Europe/Berlin"
                            },
                            "active_days": {
                              "type": "array",
                              "description": "Aktive Wochentage, 0 = Sonntag, 1 = Montag … 6 = Samstag",
                              "items": {
                                "type": "integer"
                              }
                            },
                            "activity_windows": {
                              "type": "array",
                              "description": "Uhrzeiten, in denen Aktionen laufen",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "start_hour": {
                                    "type": "integer",
                                    "description": "Beginn des Fensters, volle Stunde (0 bis 23) in der Zeitzone des Zeitplans"
                                  },
                                  "end_hour": {
                                    "type": "integer",
                                    "description": "Ende des Fensters, volle Stunde, ausschließlich"
                                  }
                                },
                                "additionalProperties": false
                              }
                            },
                            "max_leads_per_hour": {
                              "type": "integer",
                              "description": "Neue Leads je Stunde"
                            }
                          },
                          "additionalProperties": false
                        },
                        "daily_limits": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Tageslimits dieser Kampagne. Unabhängig davon gelten je LinkedIn-Konto 150 Vernetzungsanfragen pro Woche.",
                          "properties": {
                            "connection_requests": {
                              "type": "integer",
                              "description": "Vernetzungsanfragen pro Tag (Standard 35)"
                            },
                            "messages": {
                              "type": "integer",
                              "description": "Nachrichten pro Tag (Standard 40)"
                            },
                            "profile_views": {
                              "type": "integer",
                              "description": "Profilbesuche pro Tag (Standard 60)"
                            },
                            "follows": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Folgen pro Tag, null ohne eigenes Limit"
                            },
                            "likes": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Reaktionen auf Beiträge pro Tag, null ohne eigenes Limit"
                            }
                          },
                          "additionalProperties": false
                        },
                        "stop_conditions": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Sequenz stoppt bei Antwort bzw. Termin",
                          "properties": {
                            "on_reply": {
                              "type": "boolean",
                              "description": "Sequenz stoppt für einen Lead, sobald er antwortet (Standard true)"
                            },
                            "on_booking": {
                              "type": "boolean",
                              "description": "Sequenz stoppt für einen Lead, sobald er einen Termin bucht (Standard true)"
                            }
                          },
                          "additionalProperties": false
                        },
                        "landing_page": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Persönliche Landingpage je Lead, falls eingerichtet",
                          "properties": {
                            "template_id": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Vorlage der Landingpage, null ohne Vorlage",
                              "format": "uuid"
                            },
                            "template_name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Name der Vorlage zum Zeitpunkt der Einrichtung"
                            },
                            "video": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Video auf der Seite: static (für alle gleich), personalized (je Lead erzeugt), null ohne Video",
                              "enum": [
                                "static",
                                "personalized",
                                null
                              ]
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "c7a1e2d3-4b5c-4d6e-8f70-1a2b3c4d5e6f",
                        "name": "Geschäftsführer Logistik NRW",
                        "status": "active",
                        "orchestration_status": "running",
                        "channels": [
                          "linkedin"
                        ],
                        "campaign_type": "connect_and_message",
                        "linkedin_account": {
                          "id": "acc4e2d1-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "name": "Anna Beispiel",
                          "connection_status": "connected"
                        },
                        "sequence_id": "5e9f0a1b-2c3d-4e5f-8a6b-7c8d9e0f1a2b",
                        "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                        "progress": {
                          "total": 240,
                          "open": 150,
                          "result": 72,
                          "aborted": 18,
                          "stopped": 15,
                          "failed": 3,
                          "percent": 37
                        },
                        "start_date": "2026-10-01T08:00:00.000Z",
                        "end_date": null,
                        "created_at": "2026-09-30T14:12:00.000Z",
                        "updated_at": "2026-10-18T09:00:00.000Z",
                        "description": null,
                        "leads_count": 240,
                        "sequence": {
                          "id": "5e9f0a1b-2c3d-4e5f-8a6b-7c8d9e0f1a2b",
                          "name": "Geschäftsführer Logistik NRW Sequenz",
                          "category": "outreach",
                          "status": "active",
                          "orchestration_status": "running"
                        },
                        "schedule": {
                          "timezone": "Europe/Berlin",
                          "active_days": [
                            1,
                            2,
                            3,
                            4,
                            5
                          ],
                          "activity_windows": [
                            {
                              "start_hour": 9,
                              "end_hour": 11
                            },
                            {
                              "start_hour": 13,
                              "end_hour": 15
                            },
                            {
                              "start_hour": 16,
                              "end_hour": 18
                            }
                          ],
                          "max_leads_per_hour": 3
                        },
                        "daily_limits": {
                          "connection_requests": 25,
                          "messages": 30,
                          "profile_views": 40,
                          "follows": null,
                          "likes": null
                        },
                        "stop_conditions": {
                          "on_reply": true,
                          "on_booking": true
                        },
                        "landing_page": null
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.campaigns.view",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/campaigns/{id}/steps": {
      "get": {
        "operationId": "listCampaignSteps",
        "tags": [
          "Kampagnen"
        ],
        "summary": "Schritte der Sequenz",
        "description": "Alle Schritte der Sequenz in der Reihenfolge der App: erst der Hauptpfad, dann der Pfad nach angenommener Vernetzung (if_yes), dann der Pfad ohne Annahme (if_no), jeweils nach step_order. Texte stehen mit ihren Platzhaltern ({{first_name}}, {{company}}, {{landing_page_url}} …) so, wie die App sie zeigt; A/B-Varianten, Sprachnachrichten, Video und KI-Opener sind aufgeschlüsselt. Ohne verknüpfte Sequenz (Entwurf) ist die Liste leer.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.campaigns.view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Kampagne",
              "format": "uuid"
            },
            "description": "ID der Kampagne"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Schritts",
                            "format": "uuid"
                          },
                          "step_order": {
                            "type": "integer",
                            "description": "Reihenfolge innerhalb der Sequenz"
                          },
                          "branch": {
                            "type": "string",
                            "description": "main = Hauptpfad, if_yes = nach Annahme der Vernetzung, if_no = nicht angenommen",
                            "enum": [
                              "main",
                              "if_yes",
                              "if_no"
                            ]
                          },
                          "action_type": {
                            "type": "string",
                            "description": "view_profile, send_connection, send_message, send_voice, send_video, ai_opener, react_post, comment_post, follow, wait, withdraw_connection"
                          },
                          "label": {
                            "type": "string",
                            "description": "Name des Schritts wie im Editor"
                          },
                          "wait_minutes": {
                            "type": "integer",
                            "description": "Wartezeit in Minuten (bei wait), bzw. Frist bis zum Zurückziehen (bei withdraw_connection)"
                          },
                          "wait_minutes_max": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Obergrenze der zufälligen Wartezeit"
                          },
                          "randomized": {
                            "type": "boolean",
                            "description": "Wartezeit wird je Lead zufällig zwischen wait_minutes und wait_minutes_max gewählt"
                          },
                          "text": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Text mit Platzhaltern wie {{first_name}} oder {{landing_page_url}}; bei ai_opener die Begrüßung"
                          },
                          "variants": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "description": "A/B-Test: alle Varianten, A ist text",
                            "items": {
                              "type": "object",
                              "properties": {
                                "key": {
                                  "type": "string",
                                  "description": "Kennung der Variante, A ist der Haupttext, danach B, C …"
                                },
                                "text": {
                                  "type": "string",
                                  "description": "Text der Variante mit Platzhaltern"
                                }
                              },
                              "additionalProperties": false
                            }
                          },
                          "audio_urls": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "description": "Sprachnachrichten (je Lead wird eine zufällig gewählt)",
                            "items": {
                              "type": "string"
                            }
                          },
                          "video": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Video-Einstellungen, nur bei send_video",
                            "properties": {
                              "mode": {
                                "type": "string",
                                "description": "static: ein festes Video für alle, personalized: Video wird je Lead erzeugt",
                                "enum": [
                                  "static",
                                  "personalized"
                                ]
                              },
                              "video_url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "URL des festen Videos, nur bei static"
                              },
                              "thumbnail_url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Vorschaubild des festen Videos, nur bei static"
                              },
                              "template": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Vorlage des personalisierten Videos, nur bei personalized"
                              }
                            },
                            "additionalProperties": false
                          },
                          "reactions": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "description": "Reaktionen bei react_post (je Lead eine zufällig)",
                            "items": {
                              "type": "string"
                            }
                          },
                          "comment_image_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Bild zum Kommentar, nur bei comment_post und comment_post_image"
                          },
                          "ai_opener": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Einstellungen des KI-Openers ({{ai_opener}} im Text oder Schritt ai_opener). Leer = Standard.",
                            "additionalProperties": true
                          },
                          "ai_opener_question": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Frage, die als zweite Nachricht folgt"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "9a1b2c3d-0000-4000-8000-000000000001",
                          "step_order": 1,
                          "branch": "main",
                          "action_type": "view_profile",
                          "label": "Profil ansehen",
                          "wait_minutes": 0,
                          "wait_minutes_max": null,
                          "randomized": false,
                          "text": null,
                          "variants": null,
                          "audio_urls": null,
                          "video": null,
                          "reactions": null,
                          "comment_image_url": null,
                          "ai_opener": null,
                          "ai_opener_question": null
                        },
                        {
                          "id": "9a1b2c3d-0000-4000-8000-000000000002",
                          "step_order": 2,
                          "branch": "main",
                          "action_type": "send_connection",
                          "label": "Vernetzungsanfrage",
                          "wait_minutes": 0,
                          "wait_minutes_max": null,
                          "randomized": false,
                          "text": null,
                          "variants": null,
                          "audio_urls": null,
                          "video": null,
                          "reactions": null,
                          "comment_image_url": null,
                          "ai_opener": null,
                          "ai_opener_question": null
                        },
                        {
                          "id": "9a1b2c3d-0000-4000-8000-000000000003",
                          "step_order": 3,
                          "branch": "if_yes",
                          "action_type": "wait",
                          "label": "Warten",
                          "wait_minutes": 1440,
                          "wait_minutes_max": 1800,
                          "randomized": true,
                          "text": null,
                          "variants": null,
                          "audio_urls": null,
                          "video": null,
                          "reactions": null,
                          "comment_image_url": null,
                          "ai_opener": null,
                          "ai_opener_question": null
                        },
                        {
                          "id": "9a1b2c3d-0000-4000-8000-000000000004",
                          "step_order": 4,
                          "branch": "if_yes",
                          "action_type": "send_message",
                          "label": "Nachricht senden",
                          "wait_minutes": 0,
                          "wait_minutes_max": null,
                          "randomized": false,
                          "text": "Hallo {{first_name}}, danke fürs Vernetzen! Kurze Frage zu {{company}}: Wie gewinnt ihr gerade neue Kunden?",
                          "variants": [
                            {
                              "key": "A",
                              "text": "Hallo {{first_name}}, danke fürs Vernetzen! Kurze Frage zu {{company}}: Wie gewinnt ihr gerade neue Kunden?"
                            },
                            {
                              "key": "B",
                              "text": "Hi {{first_name}}, schön, dass wir vernetzt sind. Darf ich fragen, wie {{company}} aktuell Neukunden gewinnt?"
                            }
                          ],
                          "audio_urls": null,
                          "video": null,
                          "reactions": null,
                          "comment_image_url": null,
                          "ai_opener": null,
                          "ai_opener_question": null
                        },
                        {
                          "id": "9a1b2c3d-0000-4000-8000-000000000005",
                          "step_order": 5,
                          "branch": "if_no",
                          "action_type": "withdraw_connection",
                          "label": "Anfrage zurückziehen",
                          "wait_minutes": 20160,
                          "wait_minutes_max": null,
                          "randomized": false,
                          "text": null,
                          "variants": null,
                          "audio_urls": null,
                          "video": null,
                          "reactions": null,
                          "comment_image_url": null,
                          "ai_opener": null,
                          "ai_opener_question": null
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.campaigns.view",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/campaigns/{id}/stats": {
      "get": {
        "operationId": "getCampaignStats",
        "tags": [
          "Kampagnen"
        ],
        "summary": "Statistik und Funnel einer Kampagne",
        "description": "Gerechnet wie der Reiter „Statistiken“ der App, mit denselben Formeln: Vernetzungsanfragen gesendet und angenommen (Annahmequote), Antwortquote je Person (Nenner: Personen mit mindestens einer Nachricht, also Text, Sprache, Video oder InMail), Antworten je Nachricht (eine Antwort zählt für die letzte Nachricht davor), Termine (Lead-Status booked oder Termin gesetzt, je Person einmal), gesendet je Schritt und die Funnel-Zeilen in der Reihenfolge des Reiters. Landingpage-Besuche, Video-Aufrufe, CTA-Klicks und Buchungen gibt es, wenn die Sequenz eine Landingpage nutzt. Die Übersicht im Dashboard rechnet „erreicht“ anders (über den erreichten Schritt) und kann abweichen. Bei großen Kampagnen dauert die Antwort einige Sekunden.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.campaigns.view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Kampagne",
              "format": "uuid"
            },
            "description": "ID der Kampagne"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "campaign_id": {
                          "type": "string",
                          "description": "ID der Kampagne",
                          "format": "uuid"
                        },
                        "sequence_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Verknüpfte Sequenz, null ohne Sequenz",
                          "format": "uuid"
                        },
                        "sequence_category": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "connection (Vernetzungskampagne) oder outreach, null ohne Sequenz"
                        },
                        "calculated_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Berechnung (die Zahlen werden bei jedem Aufruf neu gerechnet)",
                          "format": "date-time"
                        },
                        "leads": {
                          "type": "object",
                          "description": "Leads der Kampagne",
                          "properties": {
                            "total": {
                              "type": "integer",
                              "description": "Eingeschriebene Leads, sonst Leads der Kampagne (Bezugsgröße der Schritte)"
                            },
                            "in_campaign": {
                              "type": "integer",
                              "description": "Leads mit dieser Kampagne (gezählt)"
                            },
                            "in_sequence": {
                              "type": "integer",
                              "description": "Zeilen in der Sequenz"
                            },
                            "active": {
                              "type": "integer",
                              "description": "Zeilen, die noch laufen (active, waiting, pending, in_progress, waiting_for_connection)"
                            },
                            "completed": {
                              "type": "integer",
                              "description": "Zeilen mit Status completed"
                            },
                            "replied": {
                              "type": "integer",
                              "description": "Zeilen mit Antwort (auch ohne vorherige Nachricht)"
                            }
                          },
                          "additionalProperties": false
                        },
                        "connections": {
                          "type": "object",
                          "description": "Vernetzung",
                          "properties": {
                            "sent": {
                              "type": "integer",
                              "description": "Leads mit gesendeter Vernetzungsanfrage"
                            },
                            "accepted": {
                              "type": "integer",
                              "description": "Davon angenommen"
                            },
                            "accepted_by_activity": {
                              "type": "integer",
                              "description": "Annahmen laut Aktivitäten (Rückfall für Altdaten)"
                            },
                            "already_connected": {
                              "type": "integer",
                              "description": "Schon vor der Kampagne vernetzt"
                            },
                            "connected_total": {
                              "type": "integer",
                              "description": "Alle vernetzten Zeilen, mit und ohne Anfrage aus der Kampagne"
                            },
                            "acceptance_rate": {
                              "type": "integer",
                              "description": "Annahmequote in Prozent"
                            }
                          },
                          "additionalProperties": false
                        },
                        "messages_sent": {
                          "type": "integer",
                          "description": "Versendete Nachrichten (Text, Sprache, Video, InMail), jede einzeln"
                        },
                        "replies": {
                          "type": "object",
                          "description": "Antworten",
                          "properties": {
                            "messaged_people": {
                              "type": "integer",
                              "description": "Personen mit mindestens einer Nachricht (Nenner)"
                            },
                            "replied_people": {
                              "type": "integer",
                              "description": "Davon geantwortet"
                            },
                            "reply_rate": {
                              "type": "integer",
                              "description": "Antwortquote je Person in Prozent"
                            },
                            "replied_before_first_message": {
                              "type": "integer",
                              "description": "Antworten, die vor der ersten Nachricht der Sequenz kamen"
                            },
                            "unattributed": {
                              "type": "integer",
                              "description": "Antworten, die keiner gezeigten Nachricht zugeordnet sind"
                            },
                            "by_message": {
                              "type": "array",
                              "description": "Antworten je Nachricht; eine Antwort zählt für die letzte Nachricht davor",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "step_order": {
                                    "type": "integer",
                                    "description": "Schritt der Nachricht (step_order)"
                                  },
                                  "label": {
                                    "type": "string",
                                    "description": "Name des Schritts wie im Reiter"
                                  },
                                  "sent": {
                                    "type": "integer",
                                    "description": "Zeilen, an die diese Nachricht ging"
                                  },
                                  "replied": {
                                    "type": "integer",
                                    "description": "Antworten nach genau dieser Nachricht"
                                  },
                                  "reply_rate": {
                                    "type": [
                                      "integer",
                                      "null"
                                    ],
                                    "description": "Antwortquote dieser Nachricht in Prozent, null ohne Versand"
                                  },
                                  "variants": {
                                    "type": "array",
                                    "description": "A/B-Varianten mit Versand, leer ohne A/B-Test",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "key": {
                                          "type": "string",
                                          "description": "Kennung der A/B-Variante (A, B, …)"
                                        },
                                        "sent": {
                                          "type": "integer",
                                          "description": "Versand dieser Variante"
                                        },
                                        "replied": {
                                          "type": "integer",
                                          "description": "Antworten nach dieser Variante"
                                        },
                                        "reply_rate": {
                                          "type": [
                                            "integer",
                                            "null"
                                          ],
                                          "description": "Antwortquote der Variante in Prozent, null ohne Versand"
                                        }
                                      },
                                      "additionalProperties": false
                                    }
                                  }
                                },
                                "additionalProperties": false
                              }
                            }
                          },
                          "additionalProperties": false
                        },
                        "bookings": {
                          "type": "object",
                          "description": "Termine (Lead-Status booked oder Termin gesetzt, je Person einmal)",
                          "properties": {
                            "people": {
                              "type": "integer",
                              "description": "Personen mit Termin"
                            },
                            "base": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Bezugsgröße (Angeschriebene), null wenn nicht sinnvoll"
                            }
                          },
                          "additionalProperties": false
                        },
                        "funnel": {
                          "type": "array",
                          "description": "Funnel-Zeilen in der Reihenfolge des Reiters",
                          "items": {
                            "type": "object",
                            "properties": {
                              "kind": {
                                "type": "string",
                                "description": "step: ausgeführter Schritt, pre_connected: schon vernetzt, accepted: Vernetzung angenommen, replied: geantwortet, booked: Termin",
                                "enum": [
                                  "step",
                                  "pre_connected",
                                  "accepted",
                                  "replied",
                                  "booked"
                                ]
                              },
                              "action_type": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Art des Schritts, nur bei kind step"
                              },
                              "step_order": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Schritt (step_order), nur bei kind step"
                              },
                              "label": {
                                "type": "string",
                                "description": "Beschriftung der Zeile wie im Reiter"
                              },
                              "count": {
                                "type": "integer",
                                "description": "Anzahl der Leads in dieser Stufe"
                              },
                              "base": {
                                "type": "integer",
                                "description": "Bezugsgröße der Zeile"
                              },
                              "conversion_rate": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Umwandlung gegenüber der Zeile davor in Prozent"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "lead_status": {
                          "type": "object",
                          "description": "Zeilen der Sequenz je Status, gruppiert wie der Reiter",
                          "properties": {
                            "pending": {
                              "type": "integer",
                              "description": "Status pending (noch nicht gestartet)"
                            },
                            "active": {
                              "type": "integer",
                              "description": "Status active und in_progress"
                            },
                            "waiting": {
                              "type": "integer",
                              "description": "Status waiting_for_connection und waiting"
                            },
                            "replied": {
                              "type": "integer",
                              "description": "Status replied"
                            },
                            "booked": {
                              "type": "integer",
                              "description": "Status booked"
                            },
                            "completed": {
                              "type": "integer",
                              "description": "Status completed"
                            },
                            "stopped": {
                              "type": "integer",
                              "description": "Status stopped und excluded"
                            },
                            "failed": {
                              "type": "integer",
                              "description": "Status failed"
                            },
                            "paused": {
                              "type": "integer",
                              "description": "paused und paused_no_credits (hat im Reiter keine eigene Zeile)"
                            }
                          },
                          "additionalProperties": false
                        },
                        "landing_page": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Nur wenn die Sequenz {{landing_page_url}} nutzt. Eindeutige Leads je Ereignis, Anteil an den Leads der Kampagne.",
                          "properties": {
                            "visits": {
                              "type": "integer",
                              "description": "Leads mit Seitenaufruf"
                            },
                            "video_views": {
                              "type": "integer",
                              "description": "Leads, die das Video gestartet haben"
                            },
                            "cta_clicks": {
                              "type": "integer",
                              "description": "Leads mit Klick auf einen Button"
                            },
                            "bookings": {
                              "type": "integer",
                              "description": "Leads mit bestätigter Buchung über die Seite"
                            },
                            "visits_percent": {
                              "type": "integer",
                              "description": "visits in Prozent der Leads der Kampagne, gerundet"
                            },
                            "video_views_percent": {
                              "type": "integer",
                              "description": "video_views in Prozent der Leads der Kampagne, gerundet"
                            },
                            "cta_clicks_percent": {
                              "type": "integer",
                              "description": "cta_clicks in Prozent der Leads der Kampagne, gerundet"
                            },
                            "bookings_percent": {
                              "type": "integer",
                              "description": "bookings in Prozent der Leads der Kampagne, gerundet"
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "campaign_id": "c7a1e2d3-4b5c-4d6e-8f70-1a2b3c4d5e6f",
                        "sequence_id": "5e9f0a1b-2c3d-4e5f-8a6b-7c8d9e0f1a2b",
                        "sequence_category": "outreach",
                        "calculated_at": "2026-10-18T09:15:00.000Z",
                        "leads": {
                          "total": 240,
                          "in_campaign": 240,
                          "in_sequence": 240,
                          "active": 150,
                          "completed": 40,
                          "replied": 30
                        },
                        "connections": {
                          "sent": 180,
                          "accepted": 72,
                          "accepted_by_activity": 70,
                          "already_connected": 12,
                          "connected_total": 84,
                          "acceptance_rate": 40
                        },
                        "messages_sent": 95,
                        "replies": {
                          "messaged_people": 80,
                          "replied_people": 24,
                          "reply_rate": 30,
                          "replied_before_first_message": 1,
                          "unattributed": 0,
                          "by_message": [
                            {
                              "step_order": 4,
                              "label": "Nachricht gesendet",
                              "sent": 80,
                              "replied": 23,
                              "reply_rate": 29,
                              "variants": [
                                {
                                  "key": "A",
                                  "sent": 41,
                                  "replied": 13,
                                  "reply_rate": 32
                                },
                                {
                                  "key": "B",
                                  "sent": 39,
                                  "replied": 10,
                                  "reply_rate": 26
                                }
                              ]
                            }
                          ]
                        },
                        "bookings": {
                          "people": 6,
                          "base": 80
                        },
                        "funnel": [
                          {
                            "kind": "step",
                            "action_type": "view_profile",
                            "step_order": 1,
                            "label": "Profil besucht",
                            "count": 230,
                            "base": 240,
                            "conversion_rate": null
                          },
                          {
                            "kind": "pre_connected",
                            "action_type": null,
                            "step_order": null,
                            "label": "Bereits vernetzt (12)",
                            "count": 12,
                            "base": 240,
                            "conversion_rate": null
                          },
                          {
                            "kind": "step",
                            "action_type": "send_connection",
                            "step_order": 2,
                            "label": "Kontaktanfrage",
                            "count": 180,
                            "base": 240,
                            "conversion_rate": null
                          },
                          {
                            "kind": "accepted",
                            "action_type": null,
                            "step_order": null,
                            "label": "Vernetzung angenommen",
                            "count": 72,
                            "base": 180,
                            "conversion_rate": 40
                          },
                          {
                            "kind": "step",
                            "action_type": "send_message",
                            "step_order": 4,
                            "label": "Nachricht gesendet",
                            "count": 80,
                            "base": 240,
                            "conversion_rate": null
                          },
                          {
                            "kind": "replied",
                            "action_type": null,
                            "step_order": null,
                            "label": "Geantwortet",
                            "count": 24,
                            "base": 80,
                            "conversion_rate": null
                          },
                          {
                            "kind": "booked",
                            "action_type": null,
                            "step_order": null,
                            "label": "Termin gebucht",
                            "count": 6,
                            "base": 80,
                            "conversion_rate": 25
                          }
                        ],
                        "lead_status": {
                          "pending": 20,
                          "active": 60,
                          "waiting": 70,
                          "replied": 24,
                          "booked": 6,
                          "completed": 40,
                          "stopped": 15,
                          "failed": 3,
                          "paused": 2
                        },
                        "landing_page": null
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.campaigns.view",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/campaigns/{id}/leads": {
      "get": {
        "operationId": "listCampaignLeads",
        "tags": [
          "Kampagnen"
        ],
        "summary": "Leads einer Kampagne mit ihrem Stand",
        "description": "Je eingeschriebenem Lead der Stand in der Sequenz: Status, erreichter Schritt, Vernetzung, Antwort, letzte und nächste Aktion. Älteste Einschreibung zuerst. Leads, die über ein LinkedIn-Konto laufen, auf das die Person hinter dem Key keinen Zugriff hat, fehlen (wie in der App).\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.campaigns.view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Kampagne",
              "format": "uuid"
            },
            "description": "ID der Kampagne"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Stand in der Sequenz, kommagetrennt, z. B. replied,booked",
              "items": {
                "type": "string",
                "enum": [
                  "pending",
                  "active",
                  "in_progress",
                  "waiting_for_connection",
                  "paused",
                  "paused_no_credits",
                  "completed",
                  "replied",
                  "booked",
                  "failed",
                  "excluded",
                  "stopped"
                ]
              }
            },
            "description": "Stand in der Sequenz, kommagetrennt, z. B. replied,booked",
            "style": "form",
            "explode": false
          },
          {
            "name": "connection_status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Vernetzungsstand, kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "unknown",
                  "not_connected",
                  "pending",
                  "connected",
                  "withdrawn"
                ]
              }
            },
            "description": "Vernetzungsstand, kommagetrennt",
            "style": "form",
            "explode": false
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "sequence_lead_id": {
                            "type": "string",
                            "description": "Zeile des Leads in der Sequenz",
                            "format": "uuid"
                          },
                          "lead_id": {
                            "type": "string",
                            "description": "Lead (siehe /v1/leads/{id})",
                            "format": "uuid"
                          },
                          "first_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vorname aus dem Lead, sonst aus der Sequenz-Zeile"
                          },
                          "last_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nachname aus dem Lead, sonst aus der Sequenz-Zeile"
                          },
                          "company": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Firma aus dem Lead, sonst aus der Sequenz-Zeile"
                          },
                          "linkedin_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LinkedIn-Profil des Leads, null ohne Profil"
                          },
                          "status": {
                            "type": "string",
                            "description": "Stand in der Sequenz",
                            "enum": [
                              "pending",
                              "active",
                              "in_progress",
                              "waiting_for_connection",
                              "paused",
                              "paused_no_credits",
                              "completed",
                              "replied",
                              "booked",
                              "failed",
                              "excluded",
                              "stopped"
                            ]
                          },
                          "current_step_order": {
                            "type": "integer",
                            "description": "Zuletzt erreichter Schritt (step_order)"
                          },
                          "connection_status": {
                            "type": "string",
                            "description": "Vernetzungsstand: unknown, not_connected, pending (Anfrage offen), connected, withdrawn (Anfrage zurückgezogen)",
                            "enum": [
                              "unknown",
                              "not_connected",
                              "pending",
                              "connected",
                              "withdrawn"
                            ]
                          },
                          "connection_requested_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vernetzungsanfrage gesendet am, null ohne Anfrage",
                            "format": "date-time"
                          },
                          "connected_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vernetzt seit, null solange nicht vernetzt",
                            "format": "date-time"
                          },
                          "replied_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Erste Antwort am, null ohne Antwort",
                            "format": "date-time"
                          },
                          "pause_reason": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Freitext, warum der Lead gerade nicht weiterläuft, z. B. Tageslimit erreicht oder Warten auf Annahme. Enthält auch Normalzustände und interne Hinweise, ist also kein Fehlerkennzeichen. null ohne Grund"
                          },
                          "last_action_type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Art der zuletzt ausgeführten Aktion, z. B. send_connection, send_message; null vor der ersten Aktion"
                          },
                          "last_action_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der letzten Aktion",
                            "format": "date-time"
                          },
                          "next_action_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Frühester Zeitpunkt der nächsten Aktion, null, wenn keine geplant ist",
                            "format": "date-time"
                          },
                          "enrolled_at": {
                            "type": "string",
                            "description": "In die Sequenz eingeschrieben am",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Wer wartet auf Annahme?",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "sequence_lead_id": "d4c3b2a1-1234-4abc-8def-0123456789ab",
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "first_name": "Max",
                          "last_name": "Mustermann",
                          "company": "Beispiel Logistik GmbH",
                          "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                          "status": "waiting_for_connection",
                          "current_step_order": 2,
                          "connection_status": "pending",
                          "connection_requested_at": "2026-10-16T10:04:00.000Z",
                          "connected_at": null,
                          "replied_at": null,
                          "pause_reason": null,
                          "last_action_type": "send_connection",
                          "last_action_at": "2026-10-16T10:04:00.000Z",
                          "next_action_at": "2026-10-19T09:00:00.000Z",
                          "enrolled_at": "2026-10-15T08:30:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.campaigns.view",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/placeholders": {
      "get": {
        "operationId": "listPlaceholders",
        "tags": [
          "Vorlagen"
        ],
        "summary": "Platzhalter für Texte",
        "description": "Welche Platzhalter ein Text enthalten darf und was dealsky dafür einsetzt. `usage=campaign` (Standard): Texte von Kampagnen-Schritten (POST /v1/campaigns, PUT /v1/campaigns/{id}/steps). Es ist genau die Liste, gegen die diese Routen prüfen; Platzhalter mit `usable_via_api: false` kennt der Versand, die API lehnt sie beim Anlegen aber noch ab. In Kampagnen-Texten ist zusätzlich Spintax erlaubt, z. B. {Hallo|Hi}. `usage=message_template`: Nachrichtenvorlagen, die das Postfach beim Einfügen ersetzt (ohne Spintax). Gemeinsam haben beide unter anderem {{first_name}}, {{last_name}}, {{salutation}}, {{company}} und {{city}}; ein Text nur mit diesen passt überall. Platzhalter immer ohne Leerzeichen in den Klammern schreiben.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.campaigns.view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "usage",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "campaign (Standard) für Kampagnen-Texte, message_template für Nachrichtenvorlagen im Postfach",
              "enum": [
                "campaign",
                "message_template"
              ]
            },
            "description": "campaign (Standard) für Kampagnen-Texte, message_template für Nachrichtenvorlagen im Postfach"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string",
                            "description": "Name ohne Klammern"
                          },
                          "token": {
                            "type": "string",
                            "description": "So steht er im Text, z. B. {{first_name}}"
                          },
                          "label": {
                            "type": "string",
                            "description": "Name in der App"
                          },
                          "meaning": {
                            "type": "string",
                            "description": "Was beim Versand bzw. im Postfach eingesetzt wird"
                          },
                          "example": {
                            "type": "string",
                            "description": "Beispielwert, wie er im Text stehen könnte"
                          },
                          "category": {
                            "type": "string",
                            "description": "campaign: personal, company, address, outreach. message_template zusätzlich grammar und sender"
                          },
                          "usable_via_api": {
                            "type": "boolean",
                            "description": "false: der Versand kennt ihn, über die API lässt er sich noch nicht verwenden (Grund in note)"
                          },
                          "note": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Hinweis, warum der Platzhalter über die API noch nicht verwendbar ist. Sonst null"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Platzhalter für Kampagnen-Texte (Auszug)",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "key": "first_name",
                          "token": "{{first_name}}",
                          "label": "Vorname",
                          "meaning": "Vorname des Leads. Ist das Feld beim Lead leer, steht an der Stelle nichts.",
                          "example": "Max",
                          "category": "personal",
                          "usable_via_api": true,
                          "note": null
                        },
                        {
                          "key": "landing_page_url",
                          "token": "{{landing_page_url}}",
                          "label": "Landingpage URL",
                          "meaning": "Link zur persönlichen Landingpage, die dealsky je Lead aus der Landingpage-Vorlage der Kampagne erzeugt.",
                          "example": "https://app.de/lp/max",
                          "category": "outreach",
                          "usable_via_api": false,
                          "note": "Braucht eine Landingpage-Vorlage am Link, die sich über die API noch nicht einrichten lässt. Die Kampagne ohne den Link anlegen und ihn in dealsky im Builder ergänzen."
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.campaigns.view",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/message-templates": {
      "get": {
        "operationId": "listMessageTemplates",
        "tags": [
          "Vorlagen"
        ],
        "summary": "Nachrichtenvorlagen auflisten",
        "description": "Die Text-Vorlagen des Kontos, wie die App sie unter Nachrichtenvorlagen und im Postfach (Vorlagen im Eingabefeld) anbietet, neueste zuerst. Gelöschte fehlen. Weitere Arten (Sprachnachricht, Video, Landingpage, Bild, Dokument, Postfach-Sequenz) zeigt die App nur dealsky-Admins, sie fehlen hier. Eingesetzt werden Nachrichtenvorlagen im Postfach: Die App ersetzt die Platzhalter beim Einfügen in das Eingabefeld, die Person prüft den Text und sendet. Spintax löst das Postfach nicht auf. Für Kampagnen-Texte gelten andere Platzhalter (GET /v1/placeholders).\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Teil des Namens (Groß/Klein egal)",
              "maxLength": 200
            },
            "description": "Teil des Namens (Groß/Klein egal)"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Vorlagen dieser Kategorie (gespeicherter Wert)",
              "maxLength": 100
            },
            "description": "Nur Vorlagen dieser Kategorie (gespeicherter Wert)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                            "name": "Nachfassen nach der Messe",
                            "body": "Hallo {{first_name}}, schön, dass wir uns auf der Messe gesprochen haben. Passt es Ihnen, wenn ich Ihnen kurz zeige, wie {{company}} damit mehr Termine gewinnt?",
                            "category": "followup",
                            "category_label": "Follow-Up",
                            "placeholders": [
                              "first_name",
                              "company"
                            ],
                            "attachment": null,
                            "shortcut": null,
                            "created_at": "2026-10-01T08:00:00.000Z",
                            "updated_at": "2026-10-18T09:12:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Vorlage",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name der Vorlage"
                          },
                          "body": {
                            "type": "string",
                            "description": "Text mit Platzhaltern wie {{first_name}}. Leer bei einer Vorlage, die nur eine Sprachnachricht trägt"
                          },
                          "category": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kategorie, wie gespeichert (fester Wert wie opener oder ein frei angelegter Name)"
                          },
                          "category_label": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Name der Kategorie, wie die App ihn zeigt"
                          },
                          "placeholders": {
                            "type": "array",
                            "description": "Platzhalter im Text, ohne Klammern und klein geschrieben",
                            "items": {
                              "type": "string"
                            }
                          },
                          "attachment": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Anhang aus dem Postfach-Editor (Sprachnachricht, Bild oder Dokument). Nur lesbar",
                            "properties": {
                              "kind": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "audio, image oder document"
                              },
                              "url": {
                                "type": "string",
                                "description": "Adresse der angehängten Datei"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Dateiname des Anhangs"
                              },
                              "mime": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "MIME-Typ des Anhangs"
                              },
                              "size": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Größe in Byte"
                              }
                            },
                            "additionalProperties": false
                          },
                          "shortcut": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Altes Tastenkürzel im Postfach (nur lesbar)"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt der Anlage",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der letzten Änderung",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Vorlagen der Kategorie Follow-Up",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                          "name": "Nachfassen nach der Messe",
                          "body": "Hallo {{first_name}}, schön, dass wir uns auf der Messe gesprochen haben. Passt es Ihnen, wenn ich Ihnen kurz zeige, wie {{company}} damit mehr Termine gewinnt?",
                          "category": "followup",
                          "category_label": "Follow-Up",
                          "placeholders": [
                            "first_name",
                            "company"
                          ],
                          "attachment": null,
                          "shortcut": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      },
      "post": {
        "operationId": "createMessageTemplate",
        "tags": [
          "Vorlagen"
        ],
        "summary": "Nachrichtenvorlage anlegen",
        "description": "Legt eine Text-Vorlage an, mit denselben Spalten wie die App unter Nachrichtenvorlagen (Name, Text, Kurzbeschreibung aus dem Text, verwendete Platzhalter, Kategorie). Sie steht danach sofort im Postfach zur Auswahl; sonst passiert nichts, es wird nichts gesendet und es kostet nichts. Strenger als die App: Platzhalter, die das Postfach nicht ersetzt, und Spintax werden mit 400 abgelehnt, weil sie sonst wörtlich beim Kontakt ankämen. `category` muss eine vorhandene Kategorie sein (neue legt man in dealsky an). Ein Anhang lässt sich über die API nicht anlegen. Mit Test-Key: dieselben Prüfungen, nichts wird geschrieben.\n\n**Berechtigung:** `write:campaigns`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name der Vorlage",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "body": {
                    "type": "string",
                    "description": "Text, bis 8000 Zeichen. Nur Platzhalter aus GET /v1/placeholders?usage=message_template (Schreibweise {{first_name}}), keine Spintax",
                    "minLength": 1,
                    "maxLength": 8000
                  },
                  "category": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Vorhandene Kategorie (Name, Groß/Klein egal). null entfernt die Kategorie",
                    "maxLength": 100
                  }
                },
                "required": [
                  "name",
                  "body"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "name": "Nachfassen nach der Messe",
                    "body": "Hallo {{first_name}}, schön, dass wir uns auf der Messe gesprochen haben. Passt es Ihnen, wenn ich Ihnen kurz zeige, wie {{company}} damit mehr Termine gewinnt?",
                    "category": "followup"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                          "name": "Nachfassen nach der Messe",
                          "body": "Hallo {{first_name}}, schön, dass wir uns auf der Messe gesprochen haben. Passt es Ihnen, wenn ich Ihnen kurz zeige, wie {{company}} damit mehr Termine gewinnt?",
                          "category": "followup",
                          "category_label": "Follow-Up",
                          "placeholders": [
                            "first_name",
                            "company"
                          ],
                          "attachment": null,
                          "shortcut": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Vorlage",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Vorlage"
                        },
                        "body": {
                          "type": "string",
                          "description": "Text mit Platzhaltern wie {{first_name}}. Leer bei einer Vorlage, die nur eine Sprachnachricht trägt"
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kategorie, wie gespeichert (fester Wert wie opener oder ein frei angelegter Name)"
                        },
                        "category_label": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Name der Kategorie, wie die App ihn zeigt"
                        },
                        "placeholders": {
                          "type": "array",
                          "description": "Platzhalter im Text, ohne Klammern und klein geschrieben",
                          "items": {
                            "type": "string"
                          }
                        },
                        "attachment": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Anhang aus dem Postfach-Editor (Sprachnachricht, Bild oder Dokument). Nur lesbar",
                          "properties": {
                            "kind": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "audio, image oder document"
                            },
                            "url": {
                              "type": "string",
                              "description": "Adresse der angehängten Datei"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Dateiname des Anhangs"
                            },
                            "mime": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "MIME-Typ des Anhangs"
                            },
                            "size": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Größe in Byte"
                            }
                          },
                          "additionalProperties": false
                        },
                        "shortcut": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Altes Tastenkürzel im Postfach (nur lesbar)"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                        "name": "Nachfassen nach der Messe",
                        "body": "Hallo {{first_name}}, schön, dass wir uns auf der Messe gesprochen haben. Passt es Ihnen, wenn ich Ihnen kurz zeige, wie {{company}} damit mehr Termine gewinnt?",
                        "category": "followup",
                        "category_label": "Follow-Up",
                        "placeholders": [
                          "first_name",
                          "company"
                        ],
                        "attachment": null,
                        "shortcut": null,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:campaigns",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/message-templates/{id}": {
      "get": {
        "operationId": "getMessageTemplate",
        "tags": [
          "Vorlagen"
        ],
        "summary": "Eine Nachrichtenvorlage abrufen",
        "description": "Eingesetzt werden Nachrichtenvorlagen im Postfach: Die App ersetzt die Platzhalter beim Einfügen in das Eingabefeld, die Person prüft den Text und sendet. Spintax löst das Postfach nicht auf. Für Kampagnen-Texte gelten andere Platzhalter (GET /v1/placeholders).\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Vorlage",
              "format": "uuid"
            },
            "description": "ID der Vorlage"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                          "name": "Nachfassen nach der Messe",
                          "body": "Hallo {{first_name}}, schön, dass wir uns auf der Messe gesprochen haben. Passt es Ihnen, wenn ich Ihnen kurz zeige, wie {{company}} damit mehr Termine gewinnt?",
                          "category": "followup",
                          "category_label": "Follow-Up",
                          "placeholders": [
                            "first_name",
                            "company"
                          ],
                          "attachment": null,
                          "shortcut": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Vorlage",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Vorlage"
                        },
                        "body": {
                          "type": "string",
                          "description": "Text mit Platzhaltern wie {{first_name}}. Leer bei einer Vorlage, die nur eine Sprachnachricht trägt"
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kategorie, wie gespeichert (fester Wert wie opener oder ein frei angelegter Name)"
                        },
                        "category_label": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Name der Kategorie, wie die App ihn zeigt"
                        },
                        "placeholders": {
                          "type": "array",
                          "description": "Platzhalter im Text, ohne Klammern und klein geschrieben",
                          "items": {
                            "type": "string"
                          }
                        },
                        "attachment": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Anhang aus dem Postfach-Editor (Sprachnachricht, Bild oder Dokument). Nur lesbar",
                          "properties": {
                            "kind": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "audio, image oder document"
                            },
                            "url": {
                              "type": "string",
                              "description": "Adresse der angehängten Datei"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Dateiname des Anhangs"
                            },
                            "mime": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "MIME-Typ des Anhangs"
                            },
                            "size": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Größe in Byte"
                            }
                          },
                          "additionalProperties": false
                        },
                        "shortcut": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Altes Tastenkürzel im Postfach (nur lesbar)"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                        "name": "Nachfassen nach der Messe",
                        "body": "Hallo {{first_name}}, schön, dass wir uns auf der Messe gesprochen haben. Passt es Ihnen, wenn ich Ihnen kurz zeige, wie {{company}} damit mehr Termine gewinnt?",
                        "category": "followup",
                        "category_label": "Follow-Up",
                        "placeholders": [
                          "first_name",
                          "company"
                        ],
                        "attachment": null,
                        "shortcut": null,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read"
      },
      "patch": {
        "operationId": "updateMessageTemplate",
        "tags": [
          "Vorlagen"
        ],
        "summary": "Nachrichtenvorlage ändern",
        "description": "Ändert Name, Text oder Kategorie. Nur übergebene Felder; unveränderte Werte schreiben nichts. Prüfung des Texts wie beim Anlegen. Anhang und Tastenkürzel bleiben erhalten. Eine Vorlage mit Sprachnachricht hat wie in der App keinen Text (422 `voice_template_without_text`). Hat jemand die Vorlage zwischen Lesen und Schreiben geändert, kommt 409 `concurrent_update`. Mit Test-Key: dieselben Prüfungen, `would_update` nennt die Felder, die sich ändern würden.\n\n**Berechtigung:** `write:campaigns`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Vorlage",
              "format": "uuid"
            },
            "description": "ID der Vorlage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name der Vorlage",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "body": {
                    "type": "string",
                    "description": "Text, bis 8000 Zeichen. Nur Platzhalter aus GET /v1/placeholders?usage=message_template (Schreibweise {{first_name}}), keine Spintax",
                    "minLength": 1,
                    "maxLength": 8000
                  },
                  "category": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Vorhandene Kategorie (Name, Groß/Klein egal). null entfernt die Kategorie",
                    "maxLength": 100
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "name": "Nachfassen nach der Messe (kurz)",
                    "category": null
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                          "name": "Nachfassen nach der Messe",
                          "body": "Hallo {{first_name}}, schön, dass wir uns auf der Messe gesprochen haben. Passt es Ihnen, wenn ich Ihnen kurz zeige, wie {{company}} damit mehr Termine gewinnt?",
                          "category": "followup",
                          "category_label": "Follow-Up",
                          "placeholders": [
                            "first_name",
                            "company"
                          ],
                          "attachment": null,
                          "shortcut": null,
                          "created_at": "2026-10-01T08:00:00.000Z",
                          "updated_at": "2026-10-18T09:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Vorlage",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Vorlage"
                        },
                        "body": {
                          "type": "string",
                          "description": "Text mit Platzhaltern wie {{first_name}}. Leer bei einer Vorlage, die nur eine Sprachnachricht trägt"
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kategorie, wie gespeichert (fester Wert wie opener oder ein frei angelegter Name)"
                        },
                        "category_label": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Name der Kategorie, wie die App ihn zeigt"
                        },
                        "placeholders": {
                          "type": "array",
                          "description": "Platzhalter im Text, ohne Klammern und klein geschrieben",
                          "items": {
                            "type": "string"
                          }
                        },
                        "attachment": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Anhang aus dem Postfach-Editor (Sprachnachricht, Bild oder Dokument). Nur lesbar",
                          "properties": {
                            "kind": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "audio, image oder document"
                            },
                            "url": {
                              "type": "string",
                              "description": "Adresse der angehängten Datei"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Dateiname des Anhangs"
                            },
                            "mime": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "MIME-Typ des Anhangs"
                            },
                            "size": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Größe in Byte"
                            }
                          },
                          "additionalProperties": false
                        },
                        "shortcut": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Altes Tastenkürzel im Postfach (nur lesbar)"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
                        "name": "Nachfassen nach der Messe (kurz)",
                        "body": "Hallo {{first_name}}, schön, dass wir uns auf der Messe gesprochen haben. Passt es Ihnen, wenn ich Ihnen kurz zeige, wie {{company}} damit mehr Termine gewinnt?",
                        "category": null,
                        "category_label": null,
                        "placeholders": [
                          "first_name",
                          "company"
                        ],
                        "attachment": null,
                        "shortcut": null,
                        "created_at": "2026-10-01T08:00:00.000Z",
                        "updated_at": "2026-10-18T09:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:campaigns",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "write"
      },
      "delete": {
        "operationId": "deleteMessageTemplate",
        "tags": [
          "Vorlagen"
        ],
        "summary": "Nachrichtenvorlage löschen",
        "description": "Löscht die Vorlage wie die App: Sie wird ausgeblendet (is_active false) und steht nicht mehr zur Auswahl. Bereits gesendete Nachrichten und Kampagnen bleiben unberührt, denn die App kopiert den Text beim Einfügen. Mit Test-Key: `would_delete`, nichts wird geschrieben.\n\n**Berechtigung:** `write:campaigns`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Vorlage",
              "format": "uuid"
            },
            "description": "ID der Vorlage"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "true: Die Vorlage wurde gelöscht (ausgeblendet)"
                        },
                        "id": {
                          "type": "string",
                          "description": "ID der gelöschten Vorlage",
                          "format": "uuid"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "deleted": true,
                        "id": "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:campaigns",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/sequence-templates": {
      "get": {
        "operationId": "listSequenceTemplates",
        "tags": [
          "Vorlagen"
        ],
        "summary": "Sequenz-Vorlagen auflisten",
        "description": "Die wiederverwendbaren LinkedIn-Sequenzen des Kontos, wie die App sie unter Kampagnen-Sequenzen als „Wiederverwendbare Vorlagen“ zeigt und im Kampagnen-Builder unter „Bestehende Sequenz wählen“ anbietet: die von dealsky mitgelieferten Systemsequenzen und selbst angelegte Sequenzen ohne Kampagne. Neueste zuerst. Sequenzen, die zu einer Kampagne gehören, stehen unter GET /v1/campaigns/{id}/steps. Nur lesen.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.campaigns.edit` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Teil des Namens (Groß/Klein egal)",
              "maxLength": 200
            },
            "description": "Teil des Namens (Groß/Klein egal)"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Ein oder mehrere Status, kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "draft",
                  "active",
                  "paused",
                  "archived"
                ]
              }
            },
            "description": "Ein oder mehrere Status, kommagetrennt",
            "style": "form",
            "explode": false
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "system, template, own; kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "system",
                  "template",
                  "own"
                ]
              }
            },
            "description": "system, template, own; kommagetrennt",
            "style": "form",
            "explode": false
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Sequenz-Vorlage",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name der Sequenz-Vorlage"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Beschreibung der Sequenz-Vorlage"
                          },
                          "status": {
                            "type": "string",
                            "description": "draft, active, paused oder archived. Der Kampagnen-Builder bietet nur active zur Auswahl an"
                          },
                          "category": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "connection = Vernetzung, outreach = Nachrichten",
                            "enum": [
                              "connection",
                              "outreach",
                              null
                            ]
                          },
                          "campaign_type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Kampagnenart, die zu den Schritten passt (wie bei GET /v1/campaigns)",
                            "enum": [
                              "connect_only",
                              "connect_and_message",
                              "message_only",
                              null
                            ]
                          },
                          "source": {
                            "type": "string",
                            "description": "system = von dealsky mitgeliefert (in der App nur ansehen und duplizieren), template = Vorlage, own = selbst angelegt",
                            "enum": [
                              "system",
                              "template",
                              "own"
                            ]
                          },
                          "steps_count": {
                            "type": "integer",
                            "description": "Schritte ohne Wartezeiten, wie die Liste der App"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt der Anlage",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der letzten Änderung",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Systemsequenzen",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "4c590b42-1f2e-4d3c-8b4a-5e6f7a8b9c0d",
                          "name": "Sequenz Vernetzung (Vorlage)",
                          "description": null,
                          "status": "draft",
                          "category": "connection",
                          "campaign_type": "connect_only",
                          "source": "system",
                          "steps_count": 3,
                          "created_at": "2026-09-01T08:00:00.000Z",
                          "updated_at": "2026-09-01T08:00:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.campaigns.edit",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/sequence-templates/{id}": {
      "get": {
        "operationId": "getSequenceTemplate",
        "tags": [
          "Vorlagen"
        ],
        "summary": "Eine Sequenz-Vorlage mit Schritten abrufen",
        "description": "Vorlage mit allen Schritten im Format von GET /v1/campaigns/{id}/steps (Hauptpfad, dann if_yes, dann if_no). Um daraus eine Kampagne anzulegen, die Schritte an POST /v1/campaigns übergeben: action_type, branch, wait_minutes (bei wait und withdraw_connection), text, audio_urls, reactions; bei A/B-Tests text = Variante A und variants = [Text von Variante B]. Schritte mit Video oder KI-Opener sowie Texte mit {{landing_page_url}} lassen sich über die API noch nicht anlegen (GET /v1/placeholders). 404 auch für Sequenzen, die zu einer Kampagne gehören.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.campaigns.edit` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Vorlage",
              "format": "uuid"
            },
            "description": "ID der Vorlage"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "4c590b42-1f2e-4d3c-8b4a-5e6f7a8b9c0d",
                          "name": "Sequenz Vernetzung (Vorlage)",
                          "description": null,
                          "status": "draft",
                          "category": "connection",
                          "campaign_type": "connect_only",
                          "source": "system",
                          "steps_count": 3,
                          "created_at": "2026-09-01T08:00:00.000Z",
                          "updated_at": "2026-09-01T08:00:00.000Z",
                          "steps": [
                            {
                              "wait_minutes": 0,
                              "wait_minutes_max": null,
                              "randomized": false,
                              "text": null,
                              "variants": null,
                              "audio_urls": null,
                              "video": null,
                              "reactions": null,
                              "comment_image_url": null,
                              "ai_opener": null,
                              "ai_opener_question": null,
                              "id": "7b1c2d3e-0000-4000-8000-000000000001",
                              "step_order": 1,
                              "branch": "main",
                              "action_type": "view_profile",
                              "label": "Profil ansehen"
                            },
                            {
                              "wait_minutes": 1440,
                              "wait_minutes_max": 2160,
                              "randomized": true,
                              "text": null,
                              "variants": null,
                              "audio_urls": null,
                              "video": null,
                              "reactions": null,
                              "comment_image_url": null,
                              "ai_opener": null,
                              "ai_opener_question": null,
                              "id": "7b1c2d3e-0000-4000-8000-000000000002",
                              "step_order": 2,
                              "branch": "main",
                              "action_type": "wait",
                              "label": "Warten"
                            },
                            {
                              "wait_minutes": 0,
                              "wait_minutes_max": null,
                              "randomized": false,
                              "text": null,
                              "variants": null,
                              "audio_urls": null,
                              "video": null,
                              "reactions": [
                                "like"
                              ],
                              "comment_image_url": null,
                              "ai_opener": null,
                              "ai_opener_question": null,
                              "id": "7b1c2d3e-0000-4000-8000-000000000003",
                              "step_order": 3,
                              "branch": "main",
                              "action_type": "react_post",
                              "label": "Beitrag reagieren"
                            },
                            {
                              "wait_minutes": 0,
                              "wait_minutes_max": null,
                              "randomized": false,
                              "text": null,
                              "variants": null,
                              "audio_urls": null,
                              "video": null,
                              "reactions": null,
                              "comment_image_url": null,
                              "ai_opener": null,
                              "ai_opener_question": null,
                              "id": "7b1c2d3e-0000-4000-8000-000000000004",
                              "step_order": 4,
                              "branch": "main",
                              "action_type": "send_connection",
                              "label": "Vernetzungsanfrage"
                            }
                          ]
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Sequenz-Vorlage",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Sequenz-Vorlage"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Beschreibung der Sequenz-Vorlage"
                        },
                        "status": {
                          "type": "string",
                          "description": "draft, active, paused oder archived. Der Kampagnen-Builder bietet nur active zur Auswahl an"
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "connection = Vernetzung, outreach = Nachrichten",
                          "enum": [
                            "connection",
                            "outreach",
                            null
                          ]
                        },
                        "campaign_type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Kampagnenart, die zu den Schritten passt (wie bei GET /v1/campaigns)",
                          "enum": [
                            "connect_only",
                            "connect_and_message",
                            "message_only",
                            null
                          ]
                        },
                        "source": {
                          "type": "string",
                          "description": "system = von dealsky mitgeliefert (in der App nur ansehen und duplizieren), template = Vorlage, own = selbst angelegt",
                          "enum": [
                            "system",
                            "template",
                            "own"
                          ]
                        },
                        "steps_count": {
                          "type": "integer",
                          "description": "Schritte ohne Wartezeiten, wie die Liste der App"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung",
                          "format": "date-time"
                        },
                        "steps": {
                          "type": "array",
                          "description": "Schritte im Format von GET /v1/campaigns/{id}/steps",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "ID des Schritts",
                                "format": "uuid"
                              },
                              "step_order": {
                                "type": "integer",
                                "description": "Reihenfolge innerhalb der Sequenz"
                              },
                              "branch": {
                                "type": "string",
                                "description": "main = Hauptpfad, if_yes = nach Annahme der Vernetzung, if_no = nicht angenommen",
                                "enum": [
                                  "main",
                                  "if_yes",
                                  "if_no"
                                ]
                              },
                              "action_type": {
                                "type": "string",
                                "description": "view_profile, send_connection, send_message, send_voice, send_video, ai_opener, react_post, comment_post, follow, wait, withdraw_connection"
                              },
                              "label": {
                                "type": "string",
                                "description": "Name des Schritts wie im Editor"
                              },
                              "wait_minutes": {
                                "type": "integer",
                                "description": "Wartezeit in Minuten (bei wait), bzw. Frist bis zum Zurückziehen (bei withdraw_connection)"
                              },
                              "wait_minutes_max": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Obergrenze der zufälligen Wartezeit"
                              },
                              "randomized": {
                                "type": "boolean",
                                "description": "Wartezeit wird je Lead zufällig zwischen wait_minutes und wait_minutes_max gewählt"
                              },
                              "text": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Text mit Platzhaltern wie {{first_name}} oder {{landing_page_url}}; bei ai_opener die Begrüßung"
                              },
                              "variants": {
                                "type": [
                                  "array",
                                  "null"
                                ],
                                "description": "A/B-Test: alle Varianten, A ist text",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "key": {
                                      "type": "string",
                                      "description": "Kennung der Variante, A ist der Haupttext, danach B, C …"
                                    },
                                    "text": {
                                      "type": "string",
                                      "description": "Text der Variante mit Platzhaltern"
                                    }
                                  },
                                  "additionalProperties": false
                                }
                              },
                              "audio_urls": {
                                "type": [
                                  "array",
                                  "null"
                                ],
                                "description": "Sprachnachrichten (je Lead wird eine zufällig gewählt)",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "video": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "description": "Video-Einstellungen, nur bei send_video",
                                "properties": {
                                  "mode": {
                                    "type": "string",
                                    "description": "static: ein festes Video für alle, personalized: Video wird je Lead erzeugt",
                                    "enum": [
                                      "static",
                                      "personalized"
                                    ]
                                  },
                                  "video_url": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "URL des festen Videos, nur bei static"
                                  },
                                  "thumbnail_url": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Vorschaubild des festen Videos, nur bei static"
                                  },
                                  "template": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Vorlage des personalisierten Videos, nur bei personalized"
                                  }
                                },
                                "additionalProperties": false
                              },
                              "reactions": {
                                "type": [
                                  "array",
                                  "null"
                                ],
                                "description": "Reaktionen bei react_post (je Lead eine zufällig)",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "comment_image_url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Bild zum Kommentar, nur bei comment_post und comment_post_image"
                              },
                              "ai_opener": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "description": "Einstellungen des KI-Openers ({{ai_opener}} im Text oder Schritt ai_opener). Leer = Standard.",
                                "additionalProperties": true
                              },
                              "ai_opener_question": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Frage, die als zweite Nachricht folgt"
                              }
                            },
                            "additionalProperties": false
                          }
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "4c590b42-1f2e-4d3c-8b4a-5e6f7a8b9c0d",
                        "name": "Sequenz Vernetzung (Vorlage)",
                        "description": null,
                        "status": "draft",
                        "category": "connection",
                        "campaign_type": "connect_only",
                        "source": "system",
                        "steps_count": 3,
                        "created_at": "2026-09-01T08:00:00.000Z",
                        "updated_at": "2026-09-01T08:00:00.000Z",
                        "steps": [
                          {
                            "wait_minutes": 0,
                            "wait_minutes_max": null,
                            "randomized": false,
                            "text": null,
                            "variants": null,
                            "audio_urls": null,
                            "video": null,
                            "reactions": null,
                            "comment_image_url": null,
                            "ai_opener": null,
                            "ai_opener_question": null,
                            "id": "7b1c2d3e-0000-4000-8000-000000000001",
                            "step_order": 1,
                            "branch": "main",
                            "action_type": "view_profile",
                            "label": "Profil ansehen"
                          },
                          {
                            "wait_minutes": 1440,
                            "wait_minutes_max": 2160,
                            "randomized": true,
                            "text": null,
                            "variants": null,
                            "audio_urls": null,
                            "video": null,
                            "reactions": null,
                            "comment_image_url": null,
                            "ai_opener": null,
                            "ai_opener_question": null,
                            "id": "7b1c2d3e-0000-4000-8000-000000000002",
                            "step_order": 2,
                            "branch": "main",
                            "action_type": "wait",
                            "label": "Warten"
                          },
                          {
                            "wait_minutes": 0,
                            "wait_minutes_max": null,
                            "randomized": false,
                            "text": null,
                            "variants": null,
                            "audio_urls": null,
                            "video": null,
                            "reactions": [
                              "like"
                            ],
                            "comment_image_url": null,
                            "ai_opener": null,
                            "ai_opener_question": null,
                            "id": "7b1c2d3e-0000-4000-8000-000000000003",
                            "step_order": 3,
                            "branch": "main",
                            "action_type": "react_post",
                            "label": "Beitrag reagieren"
                          },
                          {
                            "wait_minutes": 0,
                            "wait_minutes_max": null,
                            "randomized": false,
                            "text": null,
                            "variants": null,
                            "audio_urls": null,
                            "video": null,
                            "reactions": null,
                            "comment_image_url": null,
                            "ai_opener": null,
                            "ai_opener_question": null,
                            "id": "7b1c2d3e-0000-4000-8000-000000000004",
                            "step_order": 4,
                            "branch": "main",
                            "action_type": "send_connection",
                            "label": "Vernetzungsanfrage"
                          }
                        ]
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.campaigns.edit",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/engage/flows": {
      "get": {
        "operationId": "listEngageFlows",
        "tags": [
          "Dauerläufe"
        ],
        "summary": "LinkedIn-Dauerläufe auflisten",
        "description": "Die Dauerläufe der Seite LinkedIn Dauerlauf, neueste zuerst, mit denselben Angaben wie die Kacheln: Status, Konto, aktive Signalquellen, Zielgruppe, Zielliste, Kampagne, Tagesziel und Kennzahlen. Sichtbar wie in der App unter LinkedIn Dauerlauf: Inhaber und Admins sehen alle Dauerläufe, Mitglieder nur die auf ihren zugewiesenen LinkedIn-Konten. Ein Dauerlauf auf einem anderen Konto ergibt 404. Liest nur gespeicherte Daten: kein Aufruf bei LinkedIn, es wird kein Kontingent verbraucht.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.lead_scout.flow_view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard und höchstens 25, je Dauerlauf werden Kennzahlen gezählt)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 25
            },
            "description": "Einträge pro Seite (Standard und höchstens 25, je Dauerlauf werden Kennzahlen gezählt)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Ein oder mehrere Status, kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "draft",
                  "active",
                  "paused",
                  "throttled",
                  "exhausted",
                  "error"
                ]
              }
            },
            "description": "Ein oder mehrere Status, kommagetrennt",
            "style": "form",
            "explode": false
          },
          {
            "name": "account_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Dauerläufe dieses LinkedIn-Kontos",
              "format": "uuid"
            },
            "description": "Nur Dauerläufe dieses LinkedIn-Kontos"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "8d2f4a1c-3b5e-4f6a-9c7d-1e2f3a4b5c6d",
                            "name": "Geschäftsführer Logistik NRW",
                            "status": "active",
                            "linkedin_account": {
                              "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                              "name": "Anna Beispiel"
                            },
                            "source_kinds": [
                              "keyword_posts",
                              "icp_search"
                            ],
                            "icp": {
                              "mode": "precision",
                              "description": "Geschäftsführer und Inhaber von Speditionen mit 20 bis 500 Mitarbeitern in Nordrhein-Westfalen",
                              "offer": "Wir digitalisieren die Disposition von Speditionen, ohne dass das Team neue Software lernen muss.",
                              "titles": [
                                "Geschäftsführer",
                                "Inhaber",
                                "Leiter Disposition"
                              ],
                              "keywords": [
                                "Spedition",
                                "Logistik"
                              ],
                              "industries": [
                                "Transport und Logistik"
                              ],
                              "locations": [
                                "Nordrhein-Westfalen, Deutschland"
                              ],
                              "company_sizes": [
                                "C",
                                "D",
                                "E"
                              ],
                              "profile_language": "de",
                              "required_keywords": [],
                              "required_keywords_mode": "any",
                              "excluded_keywords": [
                                "Student",
                                "Recruiter"
                              ],
                              "include_connections": false
                            },
                            "target_list": {
                              "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                              "name": "Dauerlauf Logistik NRW"
                            },
                            "campaign": {
                              "id": "ca6b1f2e-3d4c-4b5a-8e9f-0a1b2c3d4e5f",
                              "name": "Geschäftsführer Logistik"
                            },
                            "daily_lead_target": 15,
                            "stats": {
                              "imported_today": 6,
                              "imported_total": 214,
                              "imported_7d": 52,
                              "matched_7d": 18,
                              "rejected_7d": 140,
                              "backlog": 9,
                              "salutation_pending": 2,
                              "profile_checks_pending": 3,
                              "pending_companies": 0,
                              "sources_active": 2
                            },
                            "next_run_at": "2026-10-18T10:40:00+00:00",
                            "last_run_at": "2026-10-18T10:30:12+00:00",
                            "search_throttled_until": null,
                            "status_message": null,
                            "created_by": "7f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f",
                            "created_at": "2026-09-02T08:15:00+00:00",
                            "updated_at": "2026-10-18T10:30:12+00:00"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Dauerlaufs",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name des Dauerlaufs"
                          },
                          "status": {
                            "type": "string",
                            "description": "draft: Entwurf, läuft nicht. active: läuft. paused: pausiert. throttled: von LinkedIn gebremst. exhausted: keine neuen Quellen mehr. error: gestoppt, Grund in status_message.",
                            "enum": [
                              "draft",
                              "active",
                              "paused",
                              "throttled",
                              "exhausted",
                              "error"
                            ]
                          },
                          "linkedin_account": {
                            "type": "object",
                            "description": "LinkedIn-Konto, mit dem der Dauerlauf sucht",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Siehe GET /v1/linkedin/accounts/{id}",
                                "format": "uuid"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Anzeigename des Kontos, null, wenn nicht bekannt"
                              }
                            },
                            "additionalProperties": false
                          },
                          "source_kinds": {
                            "type": "array",
                            "description": "Aktive Signalquellen. keyword_posts: Reaktionen auf ein Thema. keyword_authors: Verfasser zu einem Thema. profile_engagers: Reaktionen auf bestimmte Profile. company_engagers: Reaktionen auf Unternehmensseiten. relations: eigene Kontakte reaktivieren. hiring_companies: Firmen, die einstellen. icp_search: direkt nach Zielgruppe suchen. profile_followers: Follower eines Profils. job_posts: Stellenanzeigen als Signal.",
                            "items": {
                              "type": "string",
                              "enum": [
                                "keyword_posts",
                                "keyword_authors",
                                "profile_engagers",
                                "company_engagers",
                                "relations",
                                "hiring_companies",
                                "icp_search",
                                "profile_followers",
                                "job_posts"
                              ]
                            }
                          },
                          "icp": {
                            "type": "object",
                            "description": "Zielgruppe wie im Abschnitt Zielgruppe der App",
                            "properties": {
                              "mode": {
                                "type": "string",
                                "description": "Strenge der KI-Prüfung: precision (streng), broad (großzügig), off (keine Prüfung, jeder Kontakt wird behalten)",
                                "enum": [
                                  "precision",
                                  "broad",
                                  "off"
                                ]
                              },
                              "description": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Zielgruppe in eigenen Worten (Maßstab der KI-Bewertung)"
                              },
                              "offer": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Eigenes Angebot, gegen das die KI die Person liest"
                              },
                              "titles": {
                                "type": "array",
                                "description": "Jobtitel der Zielgruppe",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "keywords": {
                                "type": "array",
                                "description": "Stichwörter im Profil der Zielperson",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "industries": {
                                "type": "array",
                                "description": "Branchen",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "locations": {
                                "type": "array",
                                "description": "Orte und Regionen",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "company_sizes": {
                                "type": "array",
                                "description": "Firmengrößen nach Mitarbeitern: A = 1, B = 2 bis 10, C = 11 bis 50, D = 51 bis 200, E = 201 bis 500, F = 501 bis 1.000, G = 1.001 bis 5.000, H = 5.001 bis 10.000, I = mehr als 10.000",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "A",
                                    "B",
                                    "C",
                                    "D",
                                    "E",
                                    "F",
                                    "G",
                                    "H",
                                    "I"
                                  ]
                                }
                              },
                              "profile_language": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Profilsprache (de, en, fr, es, it, nl, pt, pl, tr)"
                              },
                              "required_keywords": {
                                "type": "array",
                                "description": "Pflicht-Stichwörter aus einer früheren Fassung. In der App nicht mehr einstellbar, filtern bei Altbeständen aber weiter.",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "required_keywords_mode": {
                                "type": "string",
                                "description": "any: eines der Pflicht-Stichwörter reicht. all: alle müssen vorkommen.",
                                "enum": [
                                  "any",
                                  "all"
                                ]
                              },
                              "excluded_keywords": {
                                "type": "array",
                                "description": "Ausschluss-Stichwörter: wer sie im Profil hat, wird aussortiert",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "include_connections": {
                                "type": "boolean",
                                "description": "true: schon mit dem Konto vernetzte Personen werden übernommen. false (Standard): sie werden aussortiert."
                              }
                            },
                            "additionalProperties": false
                          },
                          "target_list": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Lead-Liste, in die übernommene Kontakte kommen. null ohne Zielliste",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "ID der Zielliste",
                                "format": "uuid"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name der Zielliste"
                              }
                            },
                            "additionalProperties": false
                          },
                          "campaign": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Verknüpfte Kampagne. null, wenn übernommene Kontakte in keine Kampagne gehen",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "ID der Kampagne, in die übernommene Kontakte automatisch eingeschrieben werden",
                                "format": "uuid"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name der Kampagne, in die übernommene Kontakte automatisch eingeschrieben werden"
                              }
                            },
                            "additionalProperties": false
                          },
                          "daily_lead_target": {
                            "type": "integer",
                            "description": "Angepeilte neue Kontakte pro Tag"
                          },
                          "stats": {
                            "type": "object",
                            "description": "Zähler des Dauerlaufs, wie die App sie am Dauerlauf zeigt",
                            "properties": {
                              "imported_today": {
                                "type": "integer",
                                "description": "Heute übernommene Kontakte (UTC-Tag, wie das Tagesziel)"
                              },
                              "imported_total": {
                                "type": "integer",
                                "description": "Alle je übernommenen Kontakte"
                              },
                              "imported_7d": {
                                "type": "integer",
                                "description": "Übernommen, in den letzten 7 Tagen gefunden"
                              },
                              "matched_7d": {
                                "type": "integer",
                                "description": "Passend bewertet, in den letzten 7 Tagen gefunden"
                              },
                              "rejected_7d": {
                                "type": "integer",
                                "description": "Aussortiert, in den letzten 7 Tagen gefunden"
                              },
                              "backlog": {
                                "type": "integer",
                                "description": "Rückstau: passend bewertete Kontakte, die auf einen freien Platz im Tagesziel warten (ohne Zeitfenster). Ab dem Doppelten des Tagesziels sucht der Dauerlauf nichts Neues, bis der Rückstau abgebaut ist."
                              },
                              "salutation_pending": {
                                "type": "integer",
                                "description": "Kontakte mit unsicherer Anrede. Sie gehen erst nach einer Entscheidung in der App in Liste und Kampagne."
                              },
                              "profile_checks_pending": {
                                "type": "integer",
                                "description": "Personen, deren Profil noch besucht wird, um Position oder Ort zu prüfen"
                              },
                              "pending_companies": {
                                "type": "integer",
                                "description": "Von „Firmen, die einstellen“ gefundene Firmen, deren Entscheider der nächste Lauf sucht"
                              },
                              "sources_active": {
                                "type": "integer",
                                "description": "Aktive Signalquellen"
                              }
                            },
                            "additionalProperties": false
                          },
                          "next_run_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nächster Lauf: früheste Fälligkeit der aktiven Quellen. Leer, wenn der Dauerlauf nicht aktiv ist.",
                            "format": "date-time"
                          },
                          "last_run_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzter Lauf des Dauerlaufs, null vor dem ersten Lauf",
                            "format": "date-time"
                          },
                          "search_throttled_until": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Suche gebremst bis (LinkedIn-Grenze erreicht)",
                            "format": "date-time"
                          },
                          "status_message": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Hinweis oder Stopp-Grund, wie ihn die App am Dauerlauf zeigt"
                          },
                          "created_by": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Team-Mitglied, das den Dauerlauf angelegt hat (siehe /v1/team)",
                            "format": "uuid"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Angelegt am",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "Zuletzt geändert am",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Alle Dauerläufe",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "8d2f4a1c-3b5e-4f6a-9c7d-1e2f3a4b5c6d",
                          "name": "Geschäftsführer Logistik NRW",
                          "status": "active",
                          "linkedin_account": {
                            "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                            "name": "Anna Beispiel"
                          },
                          "source_kinds": [
                            "keyword_posts",
                            "icp_search"
                          ],
                          "icp": {
                            "mode": "precision",
                            "description": "Geschäftsführer und Inhaber von Speditionen mit 20 bis 500 Mitarbeitern in Nordrhein-Westfalen",
                            "offer": "Wir digitalisieren die Disposition von Speditionen, ohne dass das Team neue Software lernen muss.",
                            "titles": [
                              "Geschäftsführer",
                              "Inhaber",
                              "Leiter Disposition"
                            ],
                            "keywords": [
                              "Spedition",
                              "Logistik"
                            ],
                            "industries": [
                              "Transport und Logistik"
                            ],
                            "locations": [
                              "Nordrhein-Westfalen, Deutschland"
                            ],
                            "company_sizes": [
                              "C",
                              "D",
                              "E"
                            ],
                            "profile_language": "de",
                            "required_keywords": [],
                            "required_keywords_mode": "any",
                            "excluded_keywords": [
                              "Student",
                              "Recruiter"
                            ],
                            "include_connections": false
                          },
                          "target_list": {
                            "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                            "name": "Dauerlauf Logistik NRW"
                          },
                          "campaign": {
                            "id": "ca6b1f2e-3d4c-4b5a-8e9f-0a1b2c3d4e5f",
                            "name": "Geschäftsführer Logistik"
                          },
                          "daily_lead_target": 15,
                          "stats": {
                            "imported_today": 6,
                            "imported_total": 214,
                            "imported_7d": 52,
                            "matched_7d": 18,
                            "rejected_7d": 140,
                            "backlog": 9,
                            "salutation_pending": 2,
                            "profile_checks_pending": 3,
                            "pending_companies": 0,
                            "sources_active": 2
                          },
                          "next_run_at": "2026-10-18T10:40:00+00:00",
                          "last_run_at": "2026-10-18T10:30:12+00:00",
                          "search_throttled_until": null,
                          "status_message": null,
                          "created_by": "7f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f",
                          "created_at": "2026-09-02T08:15:00+00:00",
                          "updated_at": "2026-10-18T10:30:12+00:00"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Nur aktive eines Kontos",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "8d2f4a1c-3b5e-4f6a-9c7d-1e2f3a4b5c6d",
                          "name": "Geschäftsführer Logistik NRW",
                          "status": "active",
                          "linkedin_account": {
                            "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                            "name": "Anna Beispiel"
                          },
                          "source_kinds": [
                            "keyword_posts",
                            "icp_search"
                          ],
                          "icp": {
                            "mode": "precision",
                            "description": "Geschäftsführer und Inhaber von Speditionen mit 20 bis 500 Mitarbeitern in Nordrhein-Westfalen",
                            "offer": "Wir digitalisieren die Disposition von Speditionen, ohne dass das Team neue Software lernen muss.",
                            "titles": [
                              "Geschäftsführer",
                              "Inhaber",
                              "Leiter Disposition"
                            ],
                            "keywords": [
                              "Spedition",
                              "Logistik"
                            ],
                            "industries": [
                              "Transport und Logistik"
                            ],
                            "locations": [
                              "Nordrhein-Westfalen, Deutschland"
                            ],
                            "company_sizes": [
                              "C",
                              "D",
                              "E"
                            ],
                            "profile_language": "de",
                            "required_keywords": [],
                            "required_keywords_mode": "any",
                            "excluded_keywords": [
                              "Student",
                              "Recruiter"
                            ],
                            "include_connections": false
                          },
                          "target_list": {
                            "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                            "name": "Dauerlauf Logistik NRW"
                          },
                          "campaign": {
                            "id": "ca6b1f2e-3d4c-4b5a-8e9f-0a1b2c3d4e5f",
                            "name": "Geschäftsführer Logistik"
                          },
                          "daily_lead_target": 15,
                          "stats": {
                            "imported_today": 6,
                            "imported_total": 214,
                            "imported_7d": 52,
                            "matched_7d": 18,
                            "rejected_7d": 140,
                            "backlog": 9,
                            "salutation_pending": 2,
                            "profile_checks_pending": 3,
                            "pending_companies": 0,
                            "sources_active": 2
                          },
                          "next_run_at": "2026-10-18T10:40:00+00:00",
                          "last_run_at": "2026-10-18T10:30:12+00:00",
                          "search_throttled_until": null,
                          "status_message": null,
                          "created_by": "7f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f",
                          "created_at": "2026-09-02T08:15:00+00:00",
                          "updated_at": "2026-10-18T10:30:12+00:00"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.lead_scout.flow_view",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/engage/flows/{id}": {
      "get": {
        "operationId": "getEngageFlow",
        "tags": [
          "Dauerläufe"
        ],
        "summary": "Einen LinkedIn-Dauerlauf abrufen",
        "description": "Wie die Detailseite eines Dauerlaufs: alle Angaben der Liste, dazu alle Signalquellen mit Einstellungen, Takt und Auffälligkeiten sowie das heutige Kontingent des LinkedIn-Kontos. Sichtbar wie in der App unter LinkedIn Dauerlauf: Inhaber und Admins sehen alle Dauerläufe, Mitglieder nur die auf ihren zugewiesenen LinkedIn-Konten. Ein Dauerlauf auf einem anderen Konto ergibt 404. Liest nur gespeicherte Daten: kein Aufruf bei LinkedIn, es wird kein Kontingent verbraucht.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.lead_scout.flow_view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Dauerlaufs",
              "format": "uuid"
            },
            "description": "ID des Dauerlaufs"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "8d2f4a1c-3b5e-4f6a-9c7d-1e2f3a4b5c6d",
                          "name": "Geschäftsführer Logistik NRW",
                          "status": "active",
                          "linkedin_account": {
                            "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                            "name": "Anna Beispiel"
                          },
                          "source_kinds": [
                            "keyword_posts",
                            "icp_search"
                          ],
                          "icp": {
                            "mode": "precision",
                            "description": "Geschäftsführer und Inhaber von Speditionen mit 20 bis 500 Mitarbeitern in Nordrhein-Westfalen",
                            "offer": "Wir digitalisieren die Disposition von Speditionen, ohne dass das Team neue Software lernen muss.",
                            "titles": [
                              "Geschäftsführer",
                              "Inhaber",
                              "Leiter Disposition"
                            ],
                            "keywords": [
                              "Spedition",
                              "Logistik"
                            ],
                            "industries": [
                              "Transport und Logistik"
                            ],
                            "locations": [
                              "Nordrhein-Westfalen, Deutschland"
                            ],
                            "company_sizes": [
                              "C",
                              "D",
                              "E"
                            ],
                            "profile_language": "de",
                            "required_keywords": [],
                            "required_keywords_mode": "any",
                            "excluded_keywords": [
                              "Student",
                              "Recruiter"
                            ],
                            "include_connections": false
                          },
                          "target_list": {
                            "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                            "name": "Dauerlauf Logistik NRW"
                          },
                          "campaign": {
                            "id": "ca6b1f2e-3d4c-4b5a-8e9f-0a1b2c3d4e5f",
                            "name": "Geschäftsführer Logistik"
                          },
                          "daily_lead_target": 15,
                          "stats": {
                            "imported_today": 6,
                            "imported_total": 214,
                            "imported_7d": 52,
                            "matched_7d": 18,
                            "rejected_7d": 140,
                            "backlog": 9,
                            "salutation_pending": 2,
                            "profile_checks_pending": 3,
                            "pending_companies": 0,
                            "sources_active": 2
                          },
                          "next_run_at": "2026-10-18T10:40:00+00:00",
                          "last_run_at": "2026-10-18T10:30:12+00:00",
                          "search_throttled_until": null,
                          "status_message": null,
                          "created_by": "7f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f",
                          "created_at": "2026-09-02T08:15:00+00:00",
                          "updated_at": "2026-10-18T10:30:12+00:00",
                          "sources": [
                            {
                              "id": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
                              "kind": "keyword_posts",
                              "status": "active",
                              "config": {
                                "keywords": [
                                  "Disposition",
                                  "Spedition digitalisieren"
                                ],
                                "sort_by": "date",
                                "include_reactions": true,
                                "include_comments": true,
                                "max_posts_per_run": 2
                              },
                              "next_run_at": "2026-10-18T10:40:00+00:00",
                              "last_run_at": "2026-10-18T10:30:12+00:00",
                              "consecutive_failures": 0,
                              "consecutive_empty_runs": 1,
                              "error": null
                            }
                          ],
                          "quota": {
                            "account_id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                            "date": "2026-10-18",
                            "reads": {
                              "used": 23,
                              "limit": 80,
                              "background_used": 17,
                              "background_limit": 40
                            },
                            "search_reads": {
                              "used": 310,
                              "limit": 900,
                              "background_used": 120,
                              "background_limit": 250
                            }
                          }
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Dauerlaufs",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name des Dauerlaufs"
                        },
                        "status": {
                          "type": "string",
                          "description": "draft: Entwurf, läuft nicht. active: läuft. paused: pausiert. throttled: von LinkedIn gebremst. exhausted: keine neuen Quellen mehr. error: gestoppt, Grund in status_message.",
                          "enum": [
                            "draft",
                            "active",
                            "paused",
                            "throttled",
                            "exhausted",
                            "error"
                          ]
                        },
                        "linkedin_account": {
                          "type": "object",
                          "description": "LinkedIn-Konto, mit dem der Dauerlauf sucht",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "Siehe GET /v1/linkedin/accounts/{id}",
                              "format": "uuid"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Anzeigename des Kontos, null, wenn nicht bekannt"
                            }
                          },
                          "additionalProperties": false
                        },
                        "source_kinds": {
                          "type": "array",
                          "description": "Aktive Signalquellen. keyword_posts: Reaktionen auf ein Thema. keyword_authors: Verfasser zu einem Thema. profile_engagers: Reaktionen auf bestimmte Profile. company_engagers: Reaktionen auf Unternehmensseiten. relations: eigene Kontakte reaktivieren. hiring_companies: Firmen, die einstellen. icp_search: direkt nach Zielgruppe suchen. profile_followers: Follower eines Profils. job_posts: Stellenanzeigen als Signal.",
                          "items": {
                            "type": "string",
                            "enum": [
                              "keyword_posts",
                              "keyword_authors",
                              "profile_engagers",
                              "company_engagers",
                              "relations",
                              "hiring_companies",
                              "icp_search",
                              "profile_followers",
                              "job_posts"
                            ]
                          }
                        },
                        "icp": {
                          "type": "object",
                          "description": "Zielgruppe wie im Abschnitt Zielgruppe der App",
                          "properties": {
                            "mode": {
                              "type": "string",
                              "description": "Strenge der KI-Prüfung: precision (streng), broad (großzügig), off (keine Prüfung, jeder Kontakt wird behalten)",
                              "enum": [
                                "precision",
                                "broad",
                                "off"
                              ]
                            },
                            "description": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zielgruppe in eigenen Worten (Maßstab der KI-Bewertung)"
                            },
                            "offer": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Eigenes Angebot, gegen das die KI die Person liest"
                            },
                            "titles": {
                              "type": "array",
                              "description": "Jobtitel der Zielgruppe",
                              "items": {
                                "type": "string"
                              }
                            },
                            "keywords": {
                              "type": "array",
                              "description": "Stichwörter im Profil der Zielperson",
                              "items": {
                                "type": "string"
                              }
                            },
                            "industries": {
                              "type": "array",
                              "description": "Branchen",
                              "items": {
                                "type": "string"
                              }
                            },
                            "locations": {
                              "type": "array",
                              "description": "Orte und Regionen",
                              "items": {
                                "type": "string"
                              }
                            },
                            "company_sizes": {
                              "type": "array",
                              "description": "Firmengrößen nach Mitarbeitern: A = 1, B = 2 bis 10, C = 11 bis 50, D = 51 bis 200, E = 201 bis 500, F = 501 bis 1.000, G = 1.001 bis 5.000, H = 5.001 bis 10.000, I = mehr als 10.000",
                              "items": {
                                "type": "string",
                                "enum": [
                                  "A",
                                  "B",
                                  "C",
                                  "D",
                                  "E",
                                  "F",
                                  "G",
                                  "H",
                                  "I"
                                ]
                              }
                            },
                            "profile_language": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Profilsprache (de, en, fr, es, it, nl, pt, pl, tr)"
                            },
                            "required_keywords": {
                              "type": "array",
                              "description": "Pflicht-Stichwörter aus einer früheren Fassung. In der App nicht mehr einstellbar, filtern bei Altbeständen aber weiter.",
                              "items": {
                                "type": "string"
                              }
                            },
                            "required_keywords_mode": {
                              "type": "string",
                              "description": "any: eines der Pflicht-Stichwörter reicht. all: alle müssen vorkommen.",
                              "enum": [
                                "any",
                                "all"
                              ]
                            },
                            "excluded_keywords": {
                              "type": "array",
                              "description": "Ausschluss-Stichwörter: wer sie im Profil hat, wird aussortiert",
                              "items": {
                                "type": "string"
                              }
                            },
                            "include_connections": {
                              "type": "boolean",
                              "description": "true: schon mit dem Konto vernetzte Personen werden übernommen. false (Standard): sie werden aussortiert."
                            }
                          },
                          "additionalProperties": false
                        },
                        "target_list": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Lead-Liste, in die übernommene Kontakte kommen. null ohne Zielliste",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "ID der Zielliste",
                              "format": "uuid"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Name der Zielliste"
                            }
                          },
                          "additionalProperties": false
                        },
                        "campaign": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Verknüpfte Kampagne. null, wenn übernommene Kontakte in keine Kampagne gehen",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "ID der Kampagne, in die übernommene Kontakte automatisch eingeschrieben werden",
                              "format": "uuid"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Name der Kampagne, in die übernommene Kontakte automatisch eingeschrieben werden"
                            }
                          },
                          "additionalProperties": false
                        },
                        "daily_lead_target": {
                          "type": "integer",
                          "description": "Angepeilte neue Kontakte pro Tag"
                        },
                        "stats": {
                          "type": "object",
                          "description": "Zähler des Dauerlaufs, wie die App sie am Dauerlauf zeigt",
                          "properties": {
                            "imported_today": {
                              "type": "integer",
                              "description": "Heute übernommene Kontakte (UTC-Tag, wie das Tagesziel)"
                            },
                            "imported_total": {
                              "type": "integer",
                              "description": "Alle je übernommenen Kontakte"
                            },
                            "imported_7d": {
                              "type": "integer",
                              "description": "Übernommen, in den letzten 7 Tagen gefunden"
                            },
                            "matched_7d": {
                              "type": "integer",
                              "description": "Passend bewertet, in den letzten 7 Tagen gefunden"
                            },
                            "rejected_7d": {
                              "type": "integer",
                              "description": "Aussortiert, in den letzten 7 Tagen gefunden"
                            },
                            "backlog": {
                              "type": "integer",
                              "description": "Rückstau: passend bewertete Kontakte, die auf einen freien Platz im Tagesziel warten (ohne Zeitfenster). Ab dem Doppelten des Tagesziels sucht der Dauerlauf nichts Neues, bis der Rückstau abgebaut ist."
                            },
                            "salutation_pending": {
                              "type": "integer",
                              "description": "Kontakte mit unsicherer Anrede. Sie gehen erst nach einer Entscheidung in der App in Liste und Kampagne."
                            },
                            "profile_checks_pending": {
                              "type": "integer",
                              "description": "Personen, deren Profil noch besucht wird, um Position oder Ort zu prüfen"
                            },
                            "pending_companies": {
                              "type": "integer",
                              "description": "Von „Firmen, die einstellen“ gefundene Firmen, deren Entscheider der nächste Lauf sucht"
                            },
                            "sources_active": {
                              "type": "integer",
                              "description": "Aktive Signalquellen"
                            }
                          },
                          "additionalProperties": false
                        },
                        "next_run_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nächster Lauf: früheste Fälligkeit der aktiven Quellen. Leer, wenn der Dauerlauf nicht aktiv ist.",
                          "format": "date-time"
                        },
                        "last_run_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzter Lauf des Dauerlaufs, null vor dem ersten Lauf",
                          "format": "date-time"
                        },
                        "search_throttled_until": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Suche gebremst bis (LinkedIn-Grenze erreicht)",
                          "format": "date-time"
                        },
                        "status_message": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Hinweis oder Stopp-Grund, wie ihn die App am Dauerlauf zeigt"
                        },
                        "created_by": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Team-Mitglied, das den Dauerlauf angelegt hat (siehe /v1/team)",
                          "format": "uuid"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Angelegt am",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zuletzt geändert am",
                          "format": "date-time"
                        },
                        "sources": {
                          "type": "array",
                          "description": "Alle Signalquellen, auch pausierte",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "ID der Signalquelle",
                                "format": "uuid"
                              },
                              "kind": {
                                "type": "string",
                                "description": "keyword_posts: Reaktionen auf ein Thema. keyword_authors: Verfasser zu einem Thema. profile_engagers: Reaktionen auf bestimmte Profile. company_engagers: Reaktionen auf Unternehmensseiten. relations: eigene Kontakte reaktivieren. hiring_companies: Firmen, die einstellen. icp_search: direkt nach Zielgruppe suchen. profile_followers: Follower eines Profils. job_posts: Stellenanzeigen als Signal.",
                                "enum": [
                                  "keyword_posts",
                                  "keyword_authors",
                                  "profile_engagers",
                                  "company_engagers",
                                  "relations",
                                  "hiring_companies",
                                  "icp_search",
                                  "profile_followers",
                                  "job_posts"
                                ]
                              },
                              "status": {
                                "type": "string",
                                "description": "active: läuft mit. paused: pausiert. exhausted: Schlafphase, meldet sich von selbst zurück. error: gestoppt.",
                                "enum": [
                                  "active",
                                  "paused",
                                  "exhausted",
                                  "error"
                                ]
                              },
                              "config": {
                                "type": "object",
                                "description": "Einstellungen der Quelle wie im Assistenten der App, je Art verschieden (z. B. keywords, profiles, companies, location). Interne Laufdaten (Cursor, bekannte Beiträge) sind nicht enthalten.",
                                "additionalProperties": true
                              },
                              "next_run_at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Fälligkeit. Zählt nur, solange Quelle und Dauerlauf aktiv sind.",
                                "format": "date-time"
                              },
                              "last_run_at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Letzter Lauf dieser Quelle, null vor dem ersten Lauf",
                                "format": "date-time"
                              },
                              "consecutive_failures": {
                                "type": "integer",
                                "description": "Fehlversuche in Folge; danach wartet die Quelle länger"
                              },
                              "consecutive_empty_runs": {
                                "type": "integer",
                                "description": "Läufe ohne Neues in Folge; danach schaut die Quelle seltener nach"
                              },
                              "error": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Letzte Auffälligkeit der Quelle, wie in der App"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "quota": {
                          "type": "object",
                          "description": "Heutiges LinkedIn-Kontingent des Kontos, das der Dauerlauf nutzt",
                          "examples": [
                            {
                              "account_id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                              "date": "2026-10-18",
                              "reads": {
                                "used": 23,
                                "limit": 80,
                                "background_used": 17,
                                "background_limit": 40
                              },
                              "search_reads": {
                                "used": 310,
                                "limit": 900,
                                "background_used": 120,
                                "background_limit": 250
                              }
                            }
                          ],
                          "properties": {
                            "account_id": {
                              "type": "string",
                              "description": "LinkedIn-Konto. Das Kontingent gilt je Konto, alle Dauerläufe des Kontos teilen es.",
                              "format": "uuid"
                            },
                            "date": {
                              "type": "string",
                              "description": "Tag der Zähler (UTC)",
                              "format": "date"
                            },
                            "reads": {
                              "type": "object",
                              "description": "Lese-Abrufe bei LinkedIn (Reaktionen und Kommentare)",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "heute verbraucht, alle Wege zusammen"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Tagesgrenze"
                                },
                                "background_used": {
                                  "type": "integer",
                                  "description": "davon durch Dauerläufe im Hintergrund"
                                },
                                "background_limit": {
                                  "type": "integer",
                                  "description": "Grenze für Dauerläufe im Hintergrund, innerhalb der Tagesgrenze"
                                }
                              },
                              "additionalProperties": false
                            },
                            "search_reads": {
                              "type": "object",
                              "description": "Suchtreffer, geteilt mit der LinkedIn-Suche der App",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "heute verbraucht, alle Wege zusammen"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Tagesgrenze"
                                },
                                "background_used": {
                                  "type": "integer",
                                  "description": "davon durch Dauerläufe im Hintergrund"
                                },
                                "background_limit": {
                                  "type": "integer",
                                  "description": "Grenze für Dauerläufe im Hintergrund, innerhalb der Tagesgrenze"
                                }
                              },
                              "additionalProperties": false
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "8d2f4a1c-3b5e-4f6a-9c7d-1e2f3a4b5c6d",
                        "name": "Geschäftsführer Logistik NRW",
                        "status": "active",
                        "linkedin_account": {
                          "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                          "name": "Anna Beispiel"
                        },
                        "source_kinds": [
                          "keyword_posts",
                          "icp_search"
                        ],
                        "icp": {
                          "mode": "precision",
                          "description": "Geschäftsführer und Inhaber von Speditionen mit 20 bis 500 Mitarbeitern in Nordrhein-Westfalen",
                          "offer": "Wir digitalisieren die Disposition von Speditionen, ohne dass das Team neue Software lernen muss.",
                          "titles": [
                            "Geschäftsführer",
                            "Inhaber",
                            "Leiter Disposition"
                          ],
                          "keywords": [
                            "Spedition",
                            "Logistik"
                          ],
                          "industries": [
                            "Transport und Logistik"
                          ],
                          "locations": [
                            "Nordrhein-Westfalen, Deutschland"
                          ],
                          "company_sizes": [
                            "C",
                            "D",
                            "E"
                          ],
                          "profile_language": "de",
                          "required_keywords": [],
                          "required_keywords_mode": "any",
                          "excluded_keywords": [
                            "Student",
                            "Recruiter"
                          ],
                          "include_connections": false
                        },
                        "target_list": {
                          "id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f",
                          "name": "Dauerlauf Logistik NRW"
                        },
                        "campaign": {
                          "id": "ca6b1f2e-3d4c-4b5a-8e9f-0a1b2c3d4e5f",
                          "name": "Geschäftsführer Logistik"
                        },
                        "daily_lead_target": 15,
                        "stats": {
                          "imported_today": 6,
                          "imported_total": 214,
                          "imported_7d": 52,
                          "matched_7d": 18,
                          "rejected_7d": 140,
                          "backlog": 9,
                          "salutation_pending": 2,
                          "profile_checks_pending": 3,
                          "pending_companies": 0,
                          "sources_active": 2
                        },
                        "next_run_at": "2026-10-18T10:40:00+00:00",
                        "last_run_at": "2026-10-18T10:30:12+00:00",
                        "search_throttled_until": null,
                        "status_message": null,
                        "created_by": "7f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f",
                        "created_at": "2026-09-02T08:15:00+00:00",
                        "updated_at": "2026-10-18T10:30:12+00:00",
                        "sources": [
                          {
                            "id": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
                            "kind": "keyword_posts",
                            "status": "active",
                            "config": {
                              "keywords": [
                                "Disposition",
                                "Spedition digitalisieren"
                              ],
                              "sort_by": "date",
                              "include_reactions": true,
                              "include_comments": true,
                              "max_posts_per_run": 2
                            },
                            "next_run_at": "2026-10-18T10:40:00+00:00",
                            "last_run_at": "2026-10-18T10:30:12+00:00",
                            "consecutive_failures": 0,
                            "consecutive_empty_runs": 1,
                            "error": null
                          }
                        ],
                        "quota": {
                          "account_id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                          "date": "2026-10-18",
                          "reads": {
                            "used": 23,
                            "limit": 80,
                            "background_used": 17,
                            "background_limit": 40
                          },
                          "search_reads": {
                            "used": 310,
                            "limit": 900,
                            "background_used": 120,
                            "background_limit": 250
                          }
                        }
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.lead_scout.flow_view",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/engage/flows/{id}/hits": {
      "get": {
        "operationId": "listEngageFlowHits",
        "tags": [
          "Dauerläufe"
        ],
        "summary": "Treffer eines LinkedIn-Dauerlaufs auflisten",
        "description": "Die Personen, die der Dauerlauf gefunden hat, neueste zuerst, wie die Reiter Leads und Aussortiert der Detailseite. Filter `decision` wie die Auswahl in der App (z. B. imported für Leads, rejected für Aussortiert). Angaben zur Person nur so weit, wie die App sie zeigt: Name, Headline, Firma, Profil-Link, Profilbild und verknüpfter Lead. Interne LinkedIn-Kennungen der Person, KI-Punktwert und erkannte Absicht gibt die API nicht heraus. Sichtbar wie in der App unter LinkedIn Dauerlauf: Inhaber und Admins sehen alle Dauerläufe, Mitglieder nur die auf ihren zugewiesenen LinkedIn-Konten. Ein Dauerlauf auf einem anderen Konto ergibt 404. Liest nur gespeicherte Daten: kein Aufruf bei LinkedIn, es wird kein Kontingent verbraucht.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.lead_scout.flow_view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Dauerlaufs",
              "format": "uuid"
            },
            "description": "ID des Dauerlaufs"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "decision",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Eine oder mehrere Entscheidungen, kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "pending",
                  "matched",
                  "rejected",
                  "duplicate",
                  "excluded",
                  "blocked_topic",
                  "imported",
                  "needs_salutation",
                  "connected"
                ]
              }
            },
            "description": "Eine oder mehrere Entscheidungen, kommagetrennt",
            "style": "form",
            "explode": false
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                            "decision": "imported",
                            "reason": "Geschäftsführer einer Spedition mit 80 Mitarbeitern, passt zur Zielgruppe.",
                            "manual_decision": null,
                            "manual_at": null,
                            "source_kind": "keyword_posts",
                            "created_at": "2026-10-18T09:12:40+00:00",
                            "decided_at": "2026-10-18T09:20:03+00:00",
                            "person": {
                              "name": "Jonas Beispiel",
                              "headline": "Geschäftsführer bei Beispiel Logistik GmbH",
                              "company": "Beispiel Logistik GmbH",
                              "profile_url": "https://www.linkedin.com/in/jonas-beispiel",
                              "avatar_url": "https://imagedelivery.net/beispiel/linkedin-avatar-jonas/public",
                              "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10"
                            }
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Treffers",
                            "format": "uuid"
                          },
                          "decision": {
                            "type": "string",
                            "description": "imported: übernommen (Reiter Leads). matched: passend, wartet auf einen Platz im Tagesziel. needs_salutation: Anrede unsicher, wartet auf Entscheidung. rejected: von der KI aussortiert. duplicate: schon als Lead vorhanden. excluded: Ausschlussliste oder von Hand ausgeschlossen. blocked_topic: Thema gesperrt. connected: schon mit dem Konto vernetzt. pending: noch nicht bewertet.",
                            "enum": [
                              "pending",
                              "matched",
                              "rejected",
                              "duplicate",
                              "excluded",
                              "blocked_topic",
                              "imported",
                              "needs_salutation",
                              "connected"
                            ]
                          },
                          "reason": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Begründung der KI-Bewertung im Wortlaut, wie in der Spalte „Begründung im Wortlaut“"
                          },
                          "manual_decision": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Von Hand korrigiert: promoted = trotz Aussortierung übernommen, excluded = von Hand ausgeschlossen. Leer: die KI hat entschieden.",
                            "enum": [
                              "promoted",
                              "excluded",
                              null
                            ]
                          },
                          "manual_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der Korrektur von Hand, null ohne manual_decision",
                            "format": "date-time"
                          },
                          "source_kind": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Signalquelle, die die Person gefunden hat. Leer bei Altzeilen ohne Quellenbezug.",
                            "enum": [
                              "keyword_posts",
                              "keyword_authors",
                              "profile_engagers",
                              "company_engagers",
                              "relations",
                              "hiring_companies",
                              "icp_search",
                              "profile_followers",
                              "job_posts",
                              null
                            ]
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Gefunden am",
                            "format": "date-time"
                          },
                          "decided_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der Entscheidung, bei imported der Übernahme",
                            "format": "date-time"
                          },
                          "person": {
                            "type": "object",
                            "description": "Angaben zur Person, so weit die App sie in der Trefferliste zeigt",
                            "properties": {
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name der Person, null, wenn nicht bekannt"
                              },
                              "headline": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "LinkedIn-Headline"
                              },
                              "company": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Firma der Person, null, wenn nicht bekannt"
                              },
                              "profile_url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "LinkedIn-Profil"
                              },
                              "avatar_url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Profilbild aus dem Profil-Cache, leer wenn keins vorliegt"
                              },
                              "lead_id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Lead, sobald die Person übernommen wurde oder schon Lead war (siehe GET /v1/leads/{id})",
                                "format": "uuid"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Übernommene Kontakte",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                          "decision": "imported",
                          "reason": "Geschäftsführer einer Spedition mit 80 Mitarbeitern, passt zur Zielgruppe.",
                          "manual_decision": null,
                          "manual_at": null,
                          "source_kind": "keyword_posts",
                          "created_at": "2026-10-18T09:12:40+00:00",
                          "decided_at": "2026-10-18T09:20:03+00:00",
                          "person": {
                            "name": "Jonas Beispiel",
                            "headline": "Geschäftsführer bei Beispiel Logistik GmbH",
                            "company": "Beispiel Logistik GmbH",
                            "profile_url": "https://www.linkedin.com/in/jonas-beispiel",
                            "avatar_url": "https://imagedelivery.net/beispiel/linkedin-avatar-jonas/public",
                            "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10"
                          }
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Aussortiert",
                    "value": {
                      "ok": true,
                      "data": [],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.lead_scout.flow_view",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/engage/flows/{id}/quota": {
      "get": {
        "operationId": "getEngageFlowQuota",
        "tags": [
          "Dauerläufe"
        ],
        "summary": "Heutiges Kontingent eines LinkedIn-Dauerlaufs",
        "description": "Wie der Kasten Heutiges Kontingent im Reiter Aktivität: Lese-Abrufe und Suchtreffer des LinkedIn-Kontos am heutigen Tag (UTC), jeweils gesamt und der Anteil der Dauerläufe, gegen die Tagesgrenzen. Das Kontingent gilt je Konto, alle Dauerläufe des Kontos und die LinkedIn-Suche teilen es. Sichtbar wie in der App unter LinkedIn Dauerlauf: Inhaber und Admins sehen alle Dauerläufe, Mitglieder nur die auf ihren zugewiesenen LinkedIn-Konten. Ein Dauerlauf auf einem anderen Konto ergibt 404. Liest nur gespeicherte Daten: kein Aufruf bei LinkedIn, es wird kein Kontingent verbraucht.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.lead_scout.flow_view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Dauerlaufs",
              "format": "uuid"
            },
            "description": "ID des Dauerlaufs"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "account_id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                          "date": "2026-10-18",
                          "reads": {
                            "used": 23,
                            "limit": 80,
                            "background_used": 17,
                            "background_limit": 40
                          },
                          "search_reads": {
                            "used": 310,
                            "limit": 900,
                            "background_used": 120,
                            "background_limit": 250
                          }
                        }
                      ],
                      "properties": {
                        "account_id": {
                          "type": "string",
                          "description": "LinkedIn-Konto. Das Kontingent gilt je Konto, alle Dauerläufe des Kontos teilen es.",
                          "format": "uuid"
                        },
                        "date": {
                          "type": "string",
                          "description": "Tag der Zähler (UTC)",
                          "format": "date"
                        },
                        "reads": {
                          "type": "object",
                          "description": "Lese-Abrufe bei LinkedIn (Reaktionen und Kommentare)",
                          "properties": {
                            "used": {
                              "type": "integer",
                              "description": "heute verbraucht, alle Wege zusammen"
                            },
                            "limit": {
                              "type": "integer",
                              "description": "Tagesgrenze"
                            },
                            "background_used": {
                              "type": "integer",
                              "description": "davon durch Dauerläufe im Hintergrund"
                            },
                            "background_limit": {
                              "type": "integer",
                              "description": "Grenze für Dauerläufe im Hintergrund, innerhalb der Tagesgrenze"
                            }
                          },
                          "additionalProperties": false
                        },
                        "search_reads": {
                          "type": "object",
                          "description": "Suchtreffer, geteilt mit der LinkedIn-Suche der App",
                          "properties": {
                            "used": {
                              "type": "integer",
                              "description": "heute verbraucht, alle Wege zusammen"
                            },
                            "limit": {
                              "type": "integer",
                              "description": "Tagesgrenze"
                            },
                            "background_used": {
                              "type": "integer",
                              "description": "davon durch Dauerläufe im Hintergrund"
                            },
                            "background_limit": {
                              "type": "integer",
                              "description": "Grenze für Dauerläufe im Hintergrund, innerhalb der Tagesgrenze"
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "account_id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                        "date": "2026-10-18",
                        "reads": {
                          "used": 23,
                          "limit": 80,
                          "background_used": 17,
                          "background_limit": 40
                        },
                        "search_reads": {
                          "used": 310,
                          "limit": 900,
                          "background_used": 120,
                          "background_limit": 250
                        }
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.lead_scout.flow_view",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/engage/flows/{id}/activity": {
      "get": {
        "operationId": "listEngageFlowActivity",
        "tags": [
          "Dauerläufe"
        ],
        "summary": "Lauf-Protokoll eines LinkedIn-Dauerlaufs",
        "description": "Wie das Lauf-Protokoll im Reiter Aktivität der Detailseite: eine Zeile je Lauf und Signalquelle, neueste zuerst, ausdrücklich auch Läufe ohne Treffer. Je Lauf: geprüfte Personen, in die Zielliste übernommen, an die Kampagne übergeben, Anrede offen, wartend auf einen Platz im Tagesziel, aussortiert, dazu der Hinweis des Laufs im Klartext und ein Fehler, falls einer auftrat. Mitglieder sehen wie in der App nur Läufe auf ihren zugewiesenen LinkedIn-Konten; Läufe aus der Zeit vor einem Kontowechsel können deshalb fehlen. Die Personen eines Laufs stehen unter GET /v1/engage/flows/{id}/hits. Sichtbar wie in der App unter LinkedIn Dauerlauf: Inhaber und Admins sehen alle Dauerläufe, Mitglieder nur die auf ihren zugewiesenen LinkedIn-Konten. Ein Dauerlauf auf einem anderen Konto ergibt 404. Liest nur gespeicherte Daten: kein Aufruf bei LinkedIn, es wird kein Kontingent verbraucht.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.lead_scout.flow_view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Dauerlaufs",
              "format": "uuid"
            },
            "description": "ID des Dauerlaufs"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b",
                            "started_at": "2026-10-18T10:30:12+00:00",
                            "source_kind": "keyword_posts",
                            "linkedin_account": {
                              "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                              "name": "Anna Beispiel"
                            },
                            "checked": 14,
                            "imported": 2,
                            "enrolled": 2,
                            "needs_salutation": 0,
                            "matched": 1,
                            "rejected": 11,
                            "note": "2 Beiträge gelesen, 14 Reaktionen geprüft. · 2 Leads an die Kampagne „Geschäftsführer Logistik“ übergeben.",
                            "error": null
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Laufs",
                            "format": "uuid"
                          },
                          "started_at": {
                            "type": "string",
                            "description": "Zeitpunkt des Laufs",
                            "format": "date-time"
                          },
                          "source_kind": {
                            "type": "string",
                            "description": "Signalquelle, die gelaufen ist. keyword_posts: Reaktionen auf ein Thema. keyword_authors: Verfasser zu einem Thema. profile_engagers: Reaktionen auf bestimmte Profile. company_engagers: Reaktionen auf Unternehmensseiten. relations: eigene Kontakte reaktivieren. hiring_companies: Firmen, die einstellen. icp_search: direkt nach Zielgruppe suchen. profile_followers: Follower eines Profils. job_posts: Stellenanzeigen als Signal.",
                            "enum": [
                              "keyword_posts",
                              "keyword_authors",
                              "profile_engagers",
                              "company_engagers",
                              "relations",
                              "hiring_companies",
                              "icp_search",
                              "profile_followers",
                              "job_posts"
                            ]
                          },
                          "linkedin_account": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "LinkedIn-Konto, mit dem der Lauf gesucht hat. Leer bei Altzeilen ohne Konto.",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "ID des LinkedIn-Kontos (siehe GET /v1/linkedin/accounts/{id})",
                                "format": "uuid"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Anzeigename des Kontos, null, wenn nicht bekannt"
                              }
                            },
                            "additionalProperties": false
                          },
                          "checked": {
                            "type": "integer",
                            "description": "Geprüfte Personen"
                          },
                          "imported": {
                            "type": "integer",
                            "description": "In die Zielliste übernommen"
                          },
                          "enrolled": {
                            "type": "integer",
                            "description": "An die Kampagne übergeben (0, wenn keine Kampagne verknüpft ist)"
                          },
                          "needs_salutation": {
                            "type": "integer",
                            "description": "Anrede unsicher, wartet auf eine Entscheidung in der App"
                          },
                          "matched": {
                            "type": "integer",
                            "description": "Passend, wartet auf einen freien Platz im Tagesziel"
                          },
                          "rejected": {
                            "type": "integer",
                            "description": "Aussortiert"
                          },
                          "note": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Hinweis des Laufs im Klartext, wie in der App (mehrere Hinweise mit · getrennt). Bei einem Lauf ohne Treffer die einzige Auskunft, z. B. gefundene Firmen, deren Entscheider der nächste Lauf sucht."
                          },
                          "error": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Fehler des Laufs, wie ihn die App zeigt"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Letzte Läufe, auch ohne Treffer",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b",
                          "started_at": "2026-10-18T10:30:12+00:00",
                          "source_kind": "keyword_posts",
                          "linkedin_account": {
                            "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                            "name": "Anna Beispiel"
                          },
                          "checked": 14,
                          "imported": 2,
                          "enrolled": 2,
                          "needs_salutation": 0,
                          "matched": 1,
                          "rejected": 11,
                          "note": "2 Beiträge gelesen, 14 Reaktionen geprüft. · 2 Leads an die Kampagne „Geschäftsführer Logistik“ übergeben.",
                          "error": null
                        },
                        {
                          "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
                          "started_at": "2026-10-18T08:50:03+00:00",
                          "source_kind": "hiring_companies",
                          "linkedin_account": {
                            "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                            "name": "Anna Beispiel"
                          },
                          "checked": 0,
                          "imported": 0,
                          "enrolled": 0,
                          "needs_salutation": 0,
                          "matched": 0,
                          "rejected": 0,
                          "note": "10 Firmen gefunden, die einstellen. Die Entscheider sucht der nächste Lauf.",
                          "error": null
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.lead_scout.flow_view",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/engage/flows/{id}/profile-checks": {
      "get": {
        "operationId": "listEngageFlowProfileChecks",
        "tags": [
          "Dauerläufe"
        ],
        "summary": "Offene Profilprüfungen eines LinkedIn-Dauerlaufs",
        "description": "Wie der Reiter Überprüfen der Detailseite: Personen, deren LinkedIn-Profil der Dauerlauf noch besucht, um Position und Standort zu prüfen, weil die KI sie ohne den Besuch nicht sicher einordnen kann. Bis dahin kommen sie weder in die Zielliste noch in eine Kampagne. Der Besuch ist für die Person sichtbar und läuft gedrosselt: nur bei aktivem Dauerlauf, in den Suchzeiten des Kontos, mit Abstand zwischen den Besuchen und mit eigener Tagesgrenze je Konto innerhalb des Limits für Profilbesuche, das sich Prüfungen und Kampagnen teilen. Reihenfolge wie die Warteschlange: beste KI-Bewertung zuerst, dann älteste. Ist das Profil geprüft, entscheidet der nächste Lauf, die Person verschwindet aus dieser Liste und steht mit ihrer Entscheidung unter GET /v1/engage/flows/{id}/hits. Die Gesamtzahl steht in stats.profile_checks_pending des Dauerlaufs. Angaben zur Person nur Name und Headline, wie in der App. Sichtbar wie in der App unter LinkedIn Dauerlauf: Inhaber und Admins sehen alle Dauerläufe, Mitglieder nur die auf ihren zugewiesenen LinkedIn-Konten. Ein Dauerlauf auf einem anderen Konto ergibt 404. Liest nur gespeicherte Daten: kein Aufruf bei LinkedIn, es wird kein Kontingent verbraucht.\n\n**Berechtigung:** `read:campaigns`\n\n**Recht in dealsky:** `outreach.lead_scout.flow_view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Dauerlaufs",
              "format": "uuid"
            },
            "description": "ID des Dauerlaufs"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "7d6c5b4a-3f2e-4d1c-9b0a-8f7e6d5c4b3a",
                            "created_at": "2026-10-18T09:12:40+00:00",
                            "person": {
                              "name": "Sabine Muster",
                              "headline": "Leitung Disposition und Fuhrpark"
                            }
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Prüfung",
                            "format": "uuid"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zur Prüfung vorgemerkt am",
                            "format": "date-time"
                          },
                          "person": {
                            "type": "object",
                            "description": "Angaben zur Person, so weit die App sie im Reiter Überprüfen zeigt",
                            "properties": {
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name der Person, null, wenn nicht bekannt"
                              },
                              "headline": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "LinkedIn-Headline. Leer, wenn LinkedIn keine geliefert hat (dann klärt erst der Profilbesuch die Rolle)."
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Offene Prüfungen",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "7d6c5b4a-3f2e-4d1c-9b0a-8f7e6d5c4b3a",
                          "created_at": "2026-10-18T09:12:40+00:00",
                          "person": {
                            "name": "Sabine Muster",
                            "headline": "Leitung Disposition und Fuhrpark"
                          }
                        },
                        {
                          "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e",
                          "created_at": "2026-10-18T09:12:40+00:00",
                          "person": {
                            "name": "Thomas Beispiel",
                            "headline": null
                          }
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Niemand wartet",
                    "value": {
                      "ok": true,
                      "data": [],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:campaigns",
        "x-dealsky-permission": "outreach.lead_scout.flow_view",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/linkedin/accounts": {
      "get": {
        "operationId": "listLinkedInAccounts",
        "tags": [
          "LinkedIn"
        ],
        "summary": "Verbundene LinkedIn-Konten auflisten",
        "description": "Die Konten unter Einstellungen, Outreach-Konten, älteste zuerst. Sichtbar sind die Konten wie in der App: Inhaber und Admins sehen alle, Mitglieder nur die ihnen zugewiesenen. Ohne das Recht für das Postfach (outreach.inbox) sieht ein Mitglied in der App kein Konto; die API antwortet dann mit 403. Zugangsdaten und interne Kennungen gibt die API nie heraus. Liest nur die gespeicherten Daten; anders als die Seite in der App stößt der Abruf keinen Abgleich mit LinkedIn an.\n\n**Berechtigung:** `read:linkedin`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "connection_status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Ein oder mehrere Status, kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "connected",
                  "pending_verification",
                  "broken",
                  "disconnected",
                  "error",
                  "reconnecting"
                ]
              }
            },
            "description": "Ein oder mehrere Status, kommagetrennt",
            "style": "form",
            "explode": false
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                            "name": "Anna Beispiel",
                            "linkedin_name": "Anna Beispiel",
                            "profile_url": "https://www.linkedin.com/in/anna-beispiel",
                            "picture_url": "https://imagedelivery.net/beispiel/linkedin-avatar-anna/public",
                            "connection_status": "connected",
                            "usable": true,
                            "sales_navigator": {
                              "status": "available",
                              "checked_at": "2026-10-15T08:30:00.000Z"
                            },
                            "connected_at": "2026-08-03T09:12:00.000Z",
                            "connected_by": "7f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Kontos in dealsky (dieselbe ID steht an Kampagnen als linkedin_account)",
                            "format": "uuid"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Anzeigename in dealsky, in der App änderbar"
                          },
                          "linkedin_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Name laut LinkedIn, beim Verbinden bestätigt"
                          },
                          "profile_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LinkedIn-Profil des Kontos"
                          },
                          "picture_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Profilbild"
                          },
                          "connection_status": {
                            "type": "string",
                            "description": "connected: verbunden und einsatzbereit. pending_verification: verbunden, Identität noch nicht bestätigt. broken: Verbindung defekt, in der App neu verbinden. disconnected: bei LinkedIn getrennt. error: sonstiger Fehler. reconnecting: Altwert.",
                            "enum": [
                              "connected",
                              "pending_verification",
                              "broken",
                              "disconnected",
                              "error",
                              "reconnecting"
                            ]
                          },
                          "usable": {
                            "type": "boolean",
                            "description": "true nur bei connected. Nur dann führen Kampagnen Schritte mit diesem Konto aus."
                          },
                          "sales_navigator": {
                            "type": "object",
                            "description": "Ob das Konto Sales Navigator hat, Stand der letzten Prüfung",
                            "properties": {
                              "status": {
                                "type": "string",
                                "description": "Zuletzt bestätigter Stand. unknown: noch nie sicher geprüft.",
                                "enum": [
                                  "available",
                                  "unavailable",
                                  "unknown"
                                ]
                              },
                              "checked_at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Zeitpunkt der Prüfung. Die App prüft neu, wenn er älter als 7 Tage ist; die API prüft nie selbst.",
                                "format": "date-time"
                              }
                            },
                            "additionalProperties": false
                          },
                          "connected_at": {
                            "type": "string",
                            "description": "Zeitpunkt, an dem das Konto in dealsky angelegt wurde",
                            "format": "date-time"
                          },
                          "connected_by": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Team-Mitglied, das das Konto verbunden hat (siehe /v1/team). Leer bei Konten vor dem 22.09.2026 und bei Verbindung durch den Support.",
                            "format": "uuid"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Alle Konten",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                          "name": "Anna Beispiel",
                          "linkedin_name": "Anna Beispiel",
                          "profile_url": "https://www.linkedin.com/in/anna-beispiel",
                          "picture_url": "https://imagedelivery.net/beispiel/linkedin-avatar-anna/public",
                          "connection_status": "connected",
                          "usable": true,
                          "sales_navigator": {
                            "status": "available",
                            "checked_at": "2026-10-15T08:30:00.000Z"
                          },
                          "connected_at": "2026-08-03T09:12:00.000Z",
                          "connected_by": "7f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Nur defekte Konten",
                    "value": {
                      "ok": true,
                      "data": [],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:linkedin",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/linkedin/accounts/{id}": {
      "get": {
        "operationId": "getLinkedInAccount",
        "tags": [
          "LinkedIn"
        ],
        "summary": "Ein LinkedIn-Konto abrufen",
        "description": "Sichtbar sind die Konten wie in der App: Inhaber und Admins sehen alle, Mitglieder nur die ihnen zugewiesenen. Ohne das Recht für das Postfach (outreach.inbox) sieht ein Mitglied in der App kein Konto; die API antwortet dann mit 403. Ein fremdes oder nicht zugewiesenes Konto ergibt 404.\n\n**Berechtigung:** `read:linkedin`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des LinkedIn-Kontos",
              "format": "uuid"
            },
            "description": "ID des LinkedIn-Kontos"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                          "name": "Anna Beispiel",
                          "linkedin_name": "Anna Beispiel",
                          "profile_url": "https://www.linkedin.com/in/anna-beispiel",
                          "picture_url": "https://imagedelivery.net/beispiel/linkedin-avatar-anna/public",
                          "connection_status": "connected",
                          "usable": true,
                          "sales_navigator": {
                            "status": "available",
                            "checked_at": "2026-10-15T08:30:00.000Z"
                          },
                          "connected_at": "2026-08-03T09:12:00.000Z",
                          "connected_by": "7f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Kontos in dealsky (dieselbe ID steht an Kampagnen als linkedin_account)",
                          "format": "uuid"
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Anzeigename in dealsky, in der App änderbar"
                        },
                        "linkedin_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Name laut LinkedIn, beim Verbinden bestätigt"
                        },
                        "profile_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "LinkedIn-Profil des Kontos"
                        },
                        "picture_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Profilbild"
                        },
                        "connection_status": {
                          "type": "string",
                          "description": "connected: verbunden und einsatzbereit. pending_verification: verbunden, Identität noch nicht bestätigt. broken: Verbindung defekt, in der App neu verbinden. disconnected: bei LinkedIn getrennt. error: sonstiger Fehler. reconnecting: Altwert.",
                          "enum": [
                            "connected",
                            "pending_verification",
                            "broken",
                            "disconnected",
                            "error",
                            "reconnecting"
                          ]
                        },
                        "usable": {
                          "type": "boolean",
                          "description": "true nur bei connected. Nur dann führen Kampagnen Schritte mit diesem Konto aus."
                        },
                        "sales_navigator": {
                          "type": "object",
                          "description": "Ob das Konto Sales Navigator hat, Stand der letzten Prüfung",
                          "properties": {
                            "status": {
                              "type": "string",
                              "description": "Zuletzt bestätigter Stand. unknown: noch nie sicher geprüft.",
                              "enum": [
                                "available",
                                "unavailable",
                                "unknown"
                              ]
                            },
                            "checked_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zeitpunkt der Prüfung. Die App prüft neu, wenn er älter als 7 Tage ist; die API prüft nie selbst.",
                              "format": "date-time"
                            }
                          },
                          "additionalProperties": false
                        },
                        "connected_at": {
                          "type": "string",
                          "description": "Zeitpunkt, an dem das Konto in dealsky angelegt wurde",
                          "format": "date-time"
                        },
                        "connected_by": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Team-Mitglied, das das Konto verbunden hat (siehe /v1/team). Leer bei Konten vor dem 22.09.2026 und bei Verbindung durch den Support.",
                          "format": "uuid"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                        "name": "Anna Beispiel",
                        "linkedin_name": "Anna Beispiel",
                        "profile_url": "https://www.linkedin.com/in/anna-beispiel",
                        "picture_url": "https://imagedelivery.net/beispiel/linkedin-avatar-anna/public",
                        "connection_status": "connected",
                        "usable": true,
                        "sales_navigator": {
                          "status": "available",
                          "checked_at": "2026-10-15T08:30:00.000Z"
                        },
                        "connected_at": "2026-08-03T09:12:00.000Z",
                        "connected_by": "7f1e2d3c-4b5a-4968-8776-5a4b3c2d1e0f"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:linkedin",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/linkedin/accounts/{id}/limits": {
      "get": {
        "operationId": "getLinkedInAccountLimits",
        "tags": [
          "LinkedIn"
        ],
        "summary": "Heutige Nutzung und Grenzen eines LinkedIn-Kontos",
        "description": "Nutzung über alle Kampagnen und Dauerläufe des Kontos, wie die Karte zu den Konto-Limits auf der Startseite und unter Kampagnen, Statistiken. `today`: Zähler des heutigen Tages gegen die festen Tagesgrenzen je Konto, die der Versand durchsetzt. Bei gleichmäßiger Verteilung über die Woche kann die Tagesgrenze für Vernetzungen niedriger liegen (Wochengrenze geteilt durch aktive Tage). `last_7_days`: heute und die 6 Tage davor gegen die Wochengrenzen. `weekly_connection_budget`: wie viel der 150 Vernetzungen je Woche laufende Kampagnen schon einplanen; dieselbe Rechnung prüft die App beim Anlegen, Nachschieben und Fortsetzen einer Kampagne. `warm_up`: Rampe je laufender Kampagne. Tageslimits einer einzelnen Kampagne stehen in GET /v1/campaigns/{id}. Liest nur die Datenbank: kein Aufruf bei LinkedIn, kein Zähler wird erhöht.\n\n**Berechtigung:** `read:linkedin`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des LinkedIn-Kontos",
              "format": "uuid"
            },
            "description": "ID des LinkedIn-Kontos"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "account_id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                          "date": "2026-10-18",
                          "today": {
                            "connection_requests": {
                              "used": 12,
                              "limit": 40
                            },
                            "messages_sent": {
                              "used": 30,
                              "limit": 80
                            },
                            "profile_views": {
                              "used": 45,
                              "limit": 110
                            },
                            "inmails_sent": {
                              "used": 0,
                              "limit": 25
                            },
                            "follows": {
                              "used": 3,
                              "limit": 40
                            },
                            "likes": {
                              "used": 4,
                              "limit": 50
                            },
                            "total_actions": {
                              "used": 94,
                              "limit": 200
                            }
                          },
                          "last_7_days": {
                            "since": "2026-10-12",
                            "connection_requests": {
                              "used": 57,
                              "limit": 150
                            },
                            "messages_sent": {
                              "used": 120,
                              "limit": 400
                            },
                            "follows": {
                              "used": 13,
                              "limit": 150
                            }
                          },
                          "weekly_connection_budget": {
                            "cap": 150,
                            "reserved": 100,
                            "free": 50
                          },
                          "warm_up": [
                            {
                              "campaign_id": "ca6b1f2e-3d4c-4b5a-8e9f-0a1b2c3d4e5f",
                              "campaign_name": "Geschäftsführer Logistik",
                              "sequence_id": "5e9a8b7c-6d5e-4f3a-9b2c-1d0e9f8a7b6c",
                              "enabled": true,
                              "profile": "lang",
                              "started_at": "2026-10-15T07:00:00.000Z",
                              "day": 3
                            }
                          ]
                        }
                      ],
                      "properties": {
                        "account_id": {
                          "type": "string",
                          "description": "ID des LinkedIn-Kontos",
                          "format": "uuid"
                        },
                        "date": {
                          "type": "string",
                          "description": "Tag der Tageszähler (UTC)",
                          "format": "date"
                        },
                        "today": {
                          "type": "object",
                          "description": "Verbrauch und Tagesgrenze je Aktion für heute (UTC). Ohne Eintrag für heute ist alles 0",
                          "properties": {
                            "connection_requests": {
                              "type": "object",
                              "description": "Vernetzungsanfragen heute",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            },
                            "messages_sent": {
                              "type": "object",
                              "description": "Nachrichten heute, auch Sprach- und Videonachrichten und KI-Opener",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            },
                            "profile_views": {
                              "type": "object",
                              "description": "Profilbesuche heute. Die Grenze enthält 30 Besuche, die nur Dauerläufe nutzen; Kampagnen planen mit höchstens 80.",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            },
                            "inmails_sent": {
                              "type": "object",
                              "description": "InMails heute",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            },
                            "follows": {
                              "type": "object",
                              "description": "Folgen heute",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            },
                            "likes": {
                              "type": "object",
                              "description": "Reaktionen und Kommentare heute",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            },
                            "total_actions": {
                              "type": "object",
                              "description": "Alle sechs Zähler zusammen. Die Grenze gilt, solange eine Sequenz keine eigene setzt.",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            }
                          },
                          "additionalProperties": false
                        },
                        "last_7_days": {
                          "type": "object",
                          "description": "Verbrauch und Wochengrenze je Aktion für heute und die 6 Tage davor",
                          "properties": {
                            "since": {
                              "type": "string",
                              "description": "Erster gezählter Tag: heute und die 6 Tage davor",
                              "format": "date"
                            },
                            "connection_requests": {
                              "type": "object",
                              "description": "Vernetzungsanfragen der letzten 7 Tage",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            },
                            "messages_sent": {
                              "type": "object",
                              "description": "Nachrichten der letzten 7 Tage",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            },
                            "follows": {
                              "type": "object",
                              "description": "Folgen der letzten 7 Tage",
                              "properties": {
                                "used": {
                                  "type": "integer",
                                  "description": "verbraucht"
                                },
                                "limit": {
                                  "type": "integer",
                                  "description": "Grenze"
                                }
                              },
                              "additionalProperties": false
                            }
                          },
                          "additionalProperties": false
                        },
                        "weekly_connection_budget": {
                          "type": "object",
                          "description": "Wochenbudget für Vernetzungsanfragen dieses Kontos und wie viel laufende Kampagnen davon belegen",
                          "properties": {
                            "cap": {
                              "type": "integer",
                              "description": "Vernetzungen je Woche und Konto"
                            },
                            "reserved": {
                              "type": "integer",
                              "description": "Wochenbedarf laufender Kampagnen auf diesem Konto mit offenen Einladungen: Tageslimit für Vernetzungen mal aktive Tage, ohne gespeichertes Limit 25 je Tag"
                            },
                            "free": {
                              "type": "integer",
                              "description": "Was eine weitere Kampagne noch einplanen kann"
                            }
                          },
                          "additionalProperties": false
                        },
                        "warm_up": {
                          "type": "array",
                          "description": "Warm-up je laufender Kampagne auf dem Konto. Ein Konto hat keinen eigenen Warm-up-Stand.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "campaign_id": {
                                "type": "string",
                                "description": "ID der laufenden Kampagne auf diesem Konto",
                                "format": "uuid"
                              },
                              "campaign_name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name der Kampagne"
                              },
                              "sequence_id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "LinkedIn-Sequenz der Kampagne, an der der Warm-up hängt. null, wenn keine gefunden wurde",
                                "format": "uuid"
                              },
                              "enabled": {
                                "type": "boolean",
                                "description": "true: Warm-up ist in der Sequenz eingeschaltet"
                              },
                              "profile": {
                                "type": "string",
                                "description": "kurz: volle Menge ab Tag 7. lang: volle Menge ab Tag 21.",
                                "enum": [
                                  "kurz",
                                  "lang"
                                ]
                              },
                              "started_at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Start der Sequenz, ab dem die Rampe zählt",
                                "format": "date-time"
                              },
                              "day": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Kalendertage seit Start (0 = Starttag). Leer ohne Warm-up oder ohne Start."
                              }
                            },
                            "additionalProperties": false
                          }
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "account_id": "4c8e2a1b-7d3f-4e5a-9b6c-1d2e3f4a5b6c",
                        "date": "2026-10-18",
                        "today": {
                          "connection_requests": {
                            "used": 12,
                            "limit": 40
                          },
                          "messages_sent": {
                            "used": 30,
                            "limit": 80
                          },
                          "profile_views": {
                            "used": 45,
                            "limit": 110
                          },
                          "inmails_sent": {
                            "used": 0,
                            "limit": 25
                          },
                          "follows": {
                            "used": 3,
                            "limit": 40
                          },
                          "likes": {
                            "used": 4,
                            "limit": 50
                          },
                          "total_actions": {
                            "used": 94,
                            "limit": 200
                          }
                        },
                        "last_7_days": {
                          "since": "2026-10-12",
                          "connection_requests": {
                            "used": 57,
                            "limit": 150
                          },
                          "messages_sent": {
                            "used": 120,
                            "limit": 400
                          },
                          "follows": {
                            "used": 13,
                            "limit": 150
                          }
                        },
                        "weekly_connection_budget": {
                          "cap": 150,
                          "reserved": 100,
                          "free": 50
                        },
                        "warm_up": [
                          {
                            "campaign_id": "ca6b1f2e-3d4c-4b5a-8e9f-0a1b2c3d4e5f",
                            "campaign_name": "Geschäftsführer Logistik",
                            "sequence_id": "5e9a8b7c-6d5e-4f3a-9b2c-1d0e9f8a7b6c",
                            "enabled": true,
                            "profile": "lang",
                            "started_at": "2026-10-15T07:00:00.000Z",
                            "day": 3
                          }
                        ]
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:linkedin",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/inbox/conversations": {
      "get": {
        "operationId": "listInboxConversations",
        "tags": [
          "Postfach"
        ],
        "summary": "Unterhaltungen im Postfach",
        "description": "Die LinkedIn-Unterhaltungen wie in der Chat-Liste des Postfachs, neueste Nachricht zuerst (order=oldest dreht es um, wie „Älteste zuerst“ in der App). Sichtbar sind wie in der App nur Unterhaltungen von verbundenen LinkedIn-Konten, auf die die Person, die den Key erzeugt hat, im Postfach Zugriff hat (Inhaber und Admins: alle Konten; Mitglieder: die ihnen zugewiesenen). Nur lesend: Die API synchronisiert nichts mit LinkedIn und markiert nichts als gelesen. Je Unterhaltung: Gegenüber, Vorschau der letzten Nachricht, Ungelesen, der Status nach der Regel des Postfachs (triage), von Hand gesetzte Angaben und, bei eingeschaltetem KI-Assistenten, die KI-Einordnung. Den vollständigen Verlauf liefert /v1/inbox/conversations/{chat_id}/messages. Suche (q) im Namen bei LinkedIn und im vollständigen Text der letzten Nachricht (ein Lead-Name, den die App nur ersatzweise anzeigt, wird nicht durchsucht). Mit triage prüft eine Anfrage höchstens 1000 Unterhaltungen; eine Seite kann dann weniger Einträge haben und trotzdem einen next_cursor.\n\n**Berechtigung:** `read:inbox`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "account_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Unterhaltungen dieses LinkedIn-Kontos",
              "format": "uuid"
            },
            "description": "Nur Unterhaltungen dieses LinkedIn-Kontos"
          },
          {
            "name": "triage",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Unterhaltungen mit diesem Status",
              "enum": [
                "needs_reply",
                "waiting",
                "snoozed",
                "done"
              ]
            },
            "description": "Nur Unterhaltungen mit diesem Status"
          },
          {
            "name": "lead_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Unterhaltungen mit diesem Lead",
              "format": "uuid"
            },
            "description": "Nur Unterhaltungen mit diesem Lead"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Suche im Namen bei LinkedIn und in der letzten Nachricht, ohne Groß/Klein",
              "maxLength": 200
            },
            "description": "Suche im Namen bei LinkedIn und in der letzten Nachricht, ohne Groß/Klein"
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "newest (Standard) oder oldest, nach der letzten Nachricht",
              "enum": [
                "newest",
                "oldest"
              ]
            },
            "description": "newest (Standard) oder oldest, nach der letzten Nachricht"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                            "account": {
                              "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                              "name": "Anna Beispiel"
                            },
                            "counterpart": {
                              "name": "Max Mustermann",
                              "profile_url": "https://www.linkedin.com/in/max-mustermann",
                              "lead_id": "5f1e2d3c-4b5a-4968-8776-655443322110"
                            },
                            "last_message": {
                              "at": "2026-10-18T09:41:12.000Z",
                              "direction": "inbound",
                              "preview": "Klingt spannend, wie läuft so ein E..."
                            },
                            "unread_count": 1,
                            "triage": "needs_reply",
                            "followup_scheduled_at": null,
                            "state": {
                              "status": null,
                              "snooze_until": null,
                              "handled_at": "2026-10-17T15:02:00.000Z",
                              "tags": [
                                "interesse",
                                "Messe"
                              ],
                              "sentiment": null
                            },
                            "classification": {
                              "category": "interesse",
                              "subcategory": null,
                              "sentiment": "positiv",
                              "stage": "soft_pitch",
                              "confidence": 0.86,
                              "reasoning": "Der Kontakt fragt nach dem Ablauf und signalisiert Interesse am Angebot.",
                              "classified_at": "2026-10-18T09:42:03.000Z"
                            },
                            "created_at": "2026-09-02T10:15:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Unterhaltung, für /v1/inbox/conversations/{chat_id}",
                            "format": "uuid"
                          },
                          "account": {
                            "type": "object",
                            "description": "Eigenes LinkedIn-Konto der Unterhaltung",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "LinkedIn-Konto, über das die Unterhaltung läuft (GET /v1/linkedin/accounts/{id})",
                                "format": "uuid"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Anzeigename des LinkedIn-Kontos in dealsky, null wenn das Konto nicht mehr verbunden ist"
                              }
                            },
                            "additionalProperties": false
                          },
                          "counterpart": {
                            "type": "object",
                            "description": "Gesprächspartner auf LinkedIn",
                            "properties": {
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name bei LinkedIn, sonst der Name des verknüpften Leads (wie in der App)"
                              },
                              "profile_url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "LinkedIn-Profil des Gegenübers, falls LinkedIn es liefert",
                                "format": "uri",
                                "maxLength": 2048
                              },
                              "lead_id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Verknüpfter Lead, falls vorhanden",
                                "format": "uuid"
                              }
                            },
                            "additionalProperties": false
                          },
                          "last_message": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Letzte Nachricht der Unterhaltung, null wenn noch keine bekannt ist",
                            "properties": {
                              "at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Zeitpunkt der letzten Nachricht (ISO 8601, UTC)",
                                "format": "date-time"
                              },
                              "direction": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "inbound = vom Kontakt, outbound = von Ihnen",
                                "enum": [
                                  "inbound",
                                  "outbound",
                                  null
                                ]
                              },
                              "preview": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Vorschau wie in der Chat-Liste der App: höchstens 35 Zeichen, sonst gekürzt mit ..."
                              }
                            },
                            "additionalProperties": false
                          },
                          "unread_count": {
                            "type": "integer",
                            "description": "Ungelesene eingehende Nachrichten (0 = gelesen)"
                          },
                          "triage": {
                            "type": "string",
                            "description": "needs_reply (Zu beantworten), waiting (Wartet), snoozed (Geplant), done (Geschlossen). Regel wie im Postfach der App.",
                            "enum": [
                              "needs_reply",
                              "waiting",
                              "snoozed",
                              "done"
                            ]
                          },
                          "followup_scheduled_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nächstes geplantes Follow-up, falls eines läuft",
                            "format": "date-time"
                          },
                          "state": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Von Hand gepflegte Angaben, null wenn nie etwas gesetzt wurde",
                            "properties": {
                              "status": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Manuell gesetzter Status in der App (Geschlossen, Später, Wieder geöffnet)",
                                "enum": [
                                  "done",
                                  "snoozed",
                                  "open",
                                  null
                                ]
                              },
                              "snooze_until": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Bei status snoozed: bis wann die Unterhaltung zurückgestellt ist (ISO 8601, UTC)",
                                "format": "date-time"
                              },
                              "handled_at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Zeitpunkt der letzten manuellen Änderung",
                                "format": "date-time"
                              },
                              "tags": {
                                "type": "array",
                                "description": "Schlagwörter der Unterhaltung (eigene und übernommene KI-Kategorien)",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "sentiment": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Von Hand gesetzte Stimmung",
                                "enum": [
                                  "positiv",
                                  "neutral",
                                  "negativ",
                                  null
                                ]
                              }
                            },
                            "additionalProperties": false
                          },
                          "classification": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "KI-Einordnung des Gesprächs. null, wenn der KI-Assistent des Postfachs ausgeschaltet ist oder noch nichts eingeordnet wurde.",
                            "properties": {
                              "category": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "KI-Antwortkategorie, z. B. interesse, question, objection, not_interested"
                              },
                              "subcategory": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Feinere KI-Kategorie, null wenn keine vergeben ist"
                              },
                              "sentiment": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Stimmung laut KI",
                                "enum": [
                                  "positiv",
                                  "neutral",
                                  "negativ",
                                  null
                                ]
                              },
                              "stage": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Gesprächsphase laut KI"
                              },
                              "confidence": {
                                "type": [
                                  "number",
                                  "null"
                                ],
                                "description": "Sicherheit der KI zwischen 0 und 1"
                              },
                              "reasoning": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Begründung der KI für die Einordnung, Freitext auf Deutsch"
                              },
                              "classified_at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Zeitpunkt der letzten KI-Einordnung (ISO 8601, UTC)",
                                "format": "date-time"
                              }
                            },
                            "additionalProperties": false
                          },
                          "created_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt, zu dem dealsky die Unterhaltung erstmals gespeichert hat (ISO 8601, UTC)",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Alles, was eine Antwort braucht",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "account": {
                            "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                            "name": "Anna Beispiel"
                          },
                          "counterpart": {
                            "name": "Max Mustermann",
                            "profile_url": "https://www.linkedin.com/in/max-mustermann",
                            "lead_id": "5f1e2d3c-4b5a-4968-8776-655443322110"
                          },
                          "last_message": {
                            "at": "2026-10-18T09:41:12.000Z",
                            "direction": "inbound",
                            "preview": "Klingt spannend, wie läuft so ein E..."
                          },
                          "unread_count": 1,
                          "triage": "needs_reply",
                          "followup_scheduled_at": null,
                          "state": {
                            "status": null,
                            "snooze_until": null,
                            "handled_at": "2026-10-17T15:02:00.000Z",
                            "tags": [
                              "interesse",
                              "Messe"
                            ],
                            "sentiment": null
                          },
                          "classification": {
                            "category": "interesse",
                            "subcategory": null,
                            "sentiment": "positiv",
                            "stage": "soft_pitch",
                            "confidence": 0.86,
                            "reasoning": "Der Kontakt fragt nach dem Ablauf und signalisiert Interesse am Angebot.",
                            "classified_at": "2026-10-18T09:42:03.000Z"
                          },
                          "created_at": "2026-09-02T10:15:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:inbox",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/inbox/conversations/{chat_id}": {
      "get": {
        "operationId": "getInboxConversation",
        "tags": [
          "Postfach"
        ],
        "summary": "Eine Unterhaltung",
        "description": "Dieselben Angaben wie in der Liste. Sichtbar sind wie in der App nur Unterhaltungen von verbundenen LinkedIn-Konten, auf die die Person, die den Key erzeugt hat, im Postfach Zugriff hat (Inhaber und Admins: alle Konten; Mitglieder: die ihnen zugewiesenen). Nur lesend: Die API synchronisiert nichts mit LinkedIn und markiert nichts als gelesen. Eine Unterhaltung außerhalb dieser Konten oder eines anderen Kontos ergibt 404.\n\n**Berechtigung:** `read:inbox`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "chat_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Unterhaltung",
              "format": "uuid"
            },
            "description": "ID der Unterhaltung"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "account": {
                            "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                            "name": "Anna Beispiel"
                          },
                          "counterpart": {
                            "name": "Max Mustermann",
                            "profile_url": "https://www.linkedin.com/in/max-mustermann",
                            "lead_id": "5f1e2d3c-4b5a-4968-8776-655443322110"
                          },
                          "last_message": {
                            "at": "2026-10-18T09:41:12.000Z",
                            "direction": "inbound",
                            "preview": "Klingt spannend, wie läuft so ein E..."
                          },
                          "unread_count": 1,
                          "triage": "needs_reply",
                          "followup_scheduled_at": null,
                          "state": {
                            "status": null,
                            "snooze_until": null,
                            "handled_at": "2026-10-17T15:02:00.000Z",
                            "tags": [
                              "interesse",
                              "Messe"
                            ],
                            "sentiment": null
                          },
                          "classification": {
                            "category": "interesse",
                            "subcategory": null,
                            "sentiment": "positiv",
                            "stage": "soft_pitch",
                            "confidence": 0.86,
                            "reasoning": "Der Kontakt fragt nach dem Ablauf und signalisiert Interesse am Angebot.",
                            "classified_at": "2026-10-18T09:42:03.000Z"
                          },
                          "created_at": "2026-09-02T10:15:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Unterhaltung, für /v1/inbox/conversations/{chat_id}",
                          "format": "uuid"
                        },
                        "account": {
                          "type": "object",
                          "description": "Eigenes LinkedIn-Konto der Unterhaltung",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "LinkedIn-Konto, über das die Unterhaltung läuft (GET /v1/linkedin/accounts/{id})",
                              "format": "uuid"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Anzeigename des LinkedIn-Kontos in dealsky, null wenn das Konto nicht mehr verbunden ist"
                            }
                          },
                          "additionalProperties": false
                        },
                        "counterpart": {
                          "type": "object",
                          "description": "Gesprächspartner auf LinkedIn",
                          "properties": {
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Name bei LinkedIn, sonst der Name des verknüpften Leads (wie in der App)"
                            },
                            "profile_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "LinkedIn-Profil des Gegenübers, falls LinkedIn es liefert",
                              "format": "uri",
                              "maxLength": 2048
                            },
                            "lead_id": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Verknüpfter Lead, falls vorhanden",
                              "format": "uuid"
                            }
                          },
                          "additionalProperties": false
                        },
                        "last_message": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Letzte Nachricht der Unterhaltung, null wenn noch keine bekannt ist",
                          "properties": {
                            "at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zeitpunkt der letzten Nachricht (ISO 8601, UTC)",
                              "format": "date-time"
                            },
                            "direction": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "inbound = vom Kontakt, outbound = von Ihnen",
                              "enum": [
                                "inbound",
                                "outbound",
                                null
                              ]
                            },
                            "preview": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Vorschau wie in der Chat-Liste der App: höchstens 35 Zeichen, sonst gekürzt mit ..."
                            }
                          },
                          "additionalProperties": false
                        },
                        "unread_count": {
                          "type": "integer",
                          "description": "Ungelesene eingehende Nachrichten (0 = gelesen)"
                        },
                        "triage": {
                          "type": "string",
                          "description": "needs_reply (Zu beantworten), waiting (Wartet), snoozed (Geplant), done (Geschlossen). Regel wie im Postfach der App.",
                          "enum": [
                            "needs_reply",
                            "waiting",
                            "snoozed",
                            "done"
                          ]
                        },
                        "followup_scheduled_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nächstes geplantes Follow-up, falls eines läuft",
                          "format": "date-time"
                        },
                        "state": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Von Hand gepflegte Angaben, null wenn nie etwas gesetzt wurde",
                          "properties": {
                            "status": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Manuell gesetzter Status in der App (Geschlossen, Später, Wieder geöffnet)",
                              "enum": [
                                "done",
                                "snoozed",
                                "open",
                                null
                              ]
                            },
                            "snooze_until": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Bei status snoozed: bis wann die Unterhaltung zurückgestellt ist (ISO 8601, UTC)",
                              "format": "date-time"
                            },
                            "handled_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zeitpunkt der letzten manuellen Änderung",
                              "format": "date-time"
                            },
                            "tags": {
                              "type": "array",
                              "description": "Schlagwörter der Unterhaltung (eigene und übernommene KI-Kategorien)",
                              "items": {
                                "type": "string"
                              }
                            },
                            "sentiment": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Von Hand gesetzte Stimmung",
                              "enum": [
                                "positiv",
                                "neutral",
                                "negativ",
                                null
                              ]
                            }
                          },
                          "additionalProperties": false
                        },
                        "classification": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "KI-Einordnung des Gesprächs. null, wenn der KI-Assistent des Postfachs ausgeschaltet ist oder noch nichts eingeordnet wurde.",
                          "properties": {
                            "category": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "KI-Antwortkategorie, z. B. interesse, question, objection, not_interested"
                            },
                            "subcategory": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Feinere KI-Kategorie, null wenn keine vergeben ist"
                            },
                            "sentiment": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Stimmung laut KI",
                              "enum": [
                                "positiv",
                                "neutral",
                                "negativ",
                                null
                              ]
                            },
                            "stage": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Gesprächsphase laut KI"
                            },
                            "confidence": {
                              "type": [
                                "number",
                                "null"
                              ],
                              "description": "Sicherheit der KI zwischen 0 und 1"
                            },
                            "reasoning": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Begründung der KI für die Einordnung, Freitext auf Deutsch"
                            },
                            "classified_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zeitpunkt der letzten KI-Einordnung (ISO 8601, UTC)",
                              "format": "date-time"
                            }
                          },
                          "additionalProperties": false
                        },
                        "created_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt, zu dem dealsky die Unterhaltung erstmals gespeichert hat (ISO 8601, UTC)",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                        "account": {
                          "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                          "name": "Anna Beispiel"
                        },
                        "counterpart": {
                          "name": "Max Mustermann",
                          "profile_url": "https://www.linkedin.com/in/max-mustermann",
                          "lead_id": "5f1e2d3c-4b5a-4968-8776-655443322110"
                        },
                        "last_message": {
                          "at": "2026-10-18T09:41:12.000Z",
                          "direction": "inbound",
                          "preview": "Klingt spannend, wie läuft so ein E..."
                        },
                        "unread_count": 1,
                        "triage": "needs_reply",
                        "followup_scheduled_at": null,
                        "state": {
                          "status": null,
                          "snooze_until": null,
                          "handled_at": "2026-10-17T15:02:00.000Z",
                          "tags": [
                            "interesse",
                            "Messe"
                          ],
                          "sentiment": null
                        },
                        "classification": {
                          "category": "interesse",
                          "subcategory": null,
                          "sentiment": "positiv",
                          "stage": "soft_pitch",
                          "confidence": 0.86,
                          "reasoning": "Der Kontakt fragt nach dem Ablauf und signalisiert Interesse am Angebot.",
                          "classified_at": "2026-10-18T09:42:03.000Z"
                        },
                        "created_at": "2026-09-02T10:15:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:inbox",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "read"
      },
      "patch": {
        "operationId": "updateInboxConversation",
        "tags": [
          "Postfach"
        ],
        "summary": "Status, Schlagwörter und Stimmung einer Unterhaltung setzen",
        "description": "Setzt den Zustand einer Unterhaltung wie die Knöpfe im Postfach der App: Schließen (`status: done`), Wiedervorlage bis zu einem Zeitpunkt (`status: snoozed` mit `snooze_until`), Wieder öffnen (`status: open`), dazu Schlagwörter und Stimmung. Nicht übergebene Felder bleiben unverändert. Die Antwort ist die Unterhaltung wie bei GET /v1/inbox/conversations/{chat_id}; `triage` folgt danach der Regel des Postfachs (eine neue Antwort des Kontakts öffnet eine geschlossene Unterhaltung wieder, eine abgelaufene Wiedervorlage ebenso). Der Status zählt wie in der App für die Kennzahl „Unbeantwortete Antworten“ im Dashboard.\n\n`tags` ersetzt die Schlagwörter vollständig (höchstens 20, `[]` entfernt alle). Erlaubt sind die eigenen Schlagwörter des Postfachs und, bei eingeschaltetem KI-Assistenten, die KI-Kategorien (beides liefert GET /v1/inbox/tags), außerdem die an der Unterhaltung schon gespeicherten. Solange an einer Unterhaltung nie Schlagwörter gespeichert wurden, zeigt die App bei eingeschaltetem KI-Assistenten die KI-Kategorie (`classification.category`) als Schlagwort an; wer sie behalten will, gibt sie mit. Ist der KI-Assistent aus, blendet die App gespeicherte KI-Kategorien aus und verwirft sie beim nächsten Speichern der Schlagwörter, die API ebenso.\n\n`add_tags` und `remove_tags` ändern die Schlagwörter schrittweise, ohne die Liste zu ersetzen, etwa damit ein KI-Agent ein Schlagwort setzt und die übrigen stehen lässt (nicht zusammen mit `tags`, miteinander schon). Grundlage ist, was die App an der Unterhaltung anzeigt: die gespeicherten Schlagwörter oder, solange dort nie welche gespeichert wurden und der KI-Assistent eingeschaltet ist, die KI-Kategorie (`classification.category`). Wie mit den Schlagwort-Chips im Postfach wird zuerst entfernt, dann hinten angefügt. Erlaubt sind dieselben Werte wie bei `tags`, Groß/Klein egal; ein Schlagwort, das schon dran ist, bzw. eines, das nicht dran ist, ändert nichts. Ändert sich insgesamt nichts, wird nichts gespeichert (auch die nur angezeigte KI-Kategorie nicht), die Antwort zeigt den unveränderten Stand und der Test-Key `fields: {}`. Mehr als 20 Schlagwörter danach ergeben 400.\n\n`sentiment` überschreibt die von der KI abgeleitete Stimmung, `null` stellt sie wieder auf automatisch. Wie in der App nur bei eingeschaltetem KI-Assistenten, sonst 422 mit `reason: inbox_ai_disabled`.\n\nÄnderbar sind wie in der App nur Unterhaltungen verbundener LinkedIn-Konten, auf die die Person, die den Key erzeugt hat, im Postfach Zugriff hat; alle anderen ergeben 404. Wirkt nicht nach außen: Es wird nichts gesendet, keine Sequenz gestoppt, kein Follow-up geändert und nichts mit LinkedIn synchronisiert; als gelesen markiert die API nichts. Einen Termin markiert dieser Endpunkt nicht. Kostet keine Credits. Mit Test-Key laufen alle Prüfungen, gespeichert wird nichts (`would_update`).\n\n**Berechtigung:** `write:inbox`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "chat_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Unterhaltung",
              "format": "uuid"
            },
            "description": "ID der Unterhaltung"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "description": "done = Schließen, snoozed = Wiedervorlage bis snooze_until, open = Wieder öffnen",
                    "enum": [
                      "open",
                      "snoozed",
                      "done"
                    ]
                  },
                  "snooze_until": {
                    "type": "string",
                    "description": "Nur mit status snoozed (dann Pflicht): Zeitpunkt in der Zukunft, ab dem die Unterhaltung wieder offen ist",
                    "format": "date-time"
                  },
                  "tags": {
                    "type": "array",
                    "description": "Ersetzt die Schlagwörter vollständig, [] entfernt alle. Werte aus GET /v1/inbox/tags oder bereits gespeicherte, Groß/Klein egal",
                    "items": {
                      "type": "string",
                      "maxLength": 200
                    },
                    "maxItems": 20
                  },
                  "add_tags": {
                    "type": "array",
                    "description": "Fügt Schlagwörter hinten an, die vorhandenen bleiben (nicht zusammen mit tags). Werte wie bei tags; ein schon vorhandenes ändert nichts",
                    "items": {
                      "type": "string",
                      "maxLength": 200
                    },
                    "maxItems": 20
                  },
                  "remove_tags": {
                    "type": "array",
                    "description": "Entfernt Schlagwörter, die übrigen bleiben (nicht zusammen mit tags). Ein nicht vorhandenes ändert nichts",
                    "items": {
                      "type": "string",
                      "maxLength": 200
                    },
                    "maxItems": 20
                  },
                  "sentiment": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Stimmung von Hand, null = wieder automatisch (nur mit KI-Assistent)",
                    "enum": [
                      "positiv",
                      "neutral",
                      "negativ",
                      null
                    ]
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Wiedervorlage in einer Woche",
                  "value": {
                    "status": "snoozed",
                    "snooze_until": "2026-10-26T09:00:00+01:00"
                  }
                },
                "beispiel2": {
                  "summary": "Schließen und verschlagworten",
                  "value": {
                    "status": "done",
                    "tags": [
                      "interesse",
                      "Messe"
                    ],
                    "sentiment": "positiv"
                  }
                },
                "beispiel3": {
                  "summary": "Ein Schlagwort ergänzen, die übrigen bleiben",
                  "value": {
                    "add_tags": [
                      "Rückruf"
                    ]
                  }
                },
                "beispiel4": {
                  "summary": "Schlagwort tauschen",
                  "value": {
                    "remove_tags": [
                      "Messe"
                    ],
                    "add_tags": [
                      "Rückruf"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "account": {
                            "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                            "name": "Anna Beispiel"
                          },
                          "counterpart": {
                            "name": "Max Mustermann",
                            "profile_url": "https://www.linkedin.com/in/max-mustermann",
                            "lead_id": "5f1e2d3c-4b5a-4968-8776-655443322110"
                          },
                          "last_message": {
                            "at": "2026-10-18T09:41:12.000Z",
                            "direction": "inbound",
                            "preview": "Klingt spannend, wie läuft so ein E..."
                          },
                          "unread_count": 1,
                          "triage": "needs_reply",
                          "followup_scheduled_at": null,
                          "state": {
                            "status": null,
                            "snooze_until": null,
                            "handled_at": "2026-10-17T15:02:00.000Z",
                            "tags": [
                              "interesse",
                              "Messe"
                            ],
                            "sentiment": null
                          },
                          "classification": {
                            "category": "interesse",
                            "subcategory": null,
                            "sentiment": "positiv",
                            "stage": "soft_pitch",
                            "confidence": 0.86,
                            "reasoning": "Der Kontakt fragt nach dem Ablauf und signalisiert Interesse am Angebot.",
                            "classified_at": "2026-10-18T09:42:03.000Z"
                          },
                          "created_at": "2026-09-02T10:15:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Unterhaltung, für /v1/inbox/conversations/{chat_id}",
                          "format": "uuid"
                        },
                        "account": {
                          "type": "object",
                          "description": "Eigenes LinkedIn-Konto der Unterhaltung",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "LinkedIn-Konto, über das die Unterhaltung läuft (GET /v1/linkedin/accounts/{id})",
                              "format": "uuid"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Anzeigename des LinkedIn-Kontos in dealsky, null wenn das Konto nicht mehr verbunden ist"
                            }
                          },
                          "additionalProperties": false
                        },
                        "counterpart": {
                          "type": "object",
                          "description": "Gesprächspartner auf LinkedIn",
                          "properties": {
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Name bei LinkedIn, sonst der Name des verknüpften Leads (wie in der App)"
                            },
                            "profile_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "LinkedIn-Profil des Gegenübers, falls LinkedIn es liefert",
                              "format": "uri",
                              "maxLength": 2048
                            },
                            "lead_id": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Verknüpfter Lead, falls vorhanden",
                              "format": "uuid"
                            }
                          },
                          "additionalProperties": false
                        },
                        "last_message": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Letzte Nachricht der Unterhaltung, null wenn noch keine bekannt ist",
                          "properties": {
                            "at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zeitpunkt der letzten Nachricht (ISO 8601, UTC)",
                              "format": "date-time"
                            },
                            "direction": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "inbound = vom Kontakt, outbound = von Ihnen",
                              "enum": [
                                "inbound",
                                "outbound",
                                null
                              ]
                            },
                            "preview": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Vorschau wie in der Chat-Liste der App: höchstens 35 Zeichen, sonst gekürzt mit ..."
                            }
                          },
                          "additionalProperties": false
                        },
                        "unread_count": {
                          "type": "integer",
                          "description": "Ungelesene eingehende Nachrichten (0 = gelesen)"
                        },
                        "triage": {
                          "type": "string",
                          "description": "needs_reply (Zu beantworten), waiting (Wartet), snoozed (Geplant), done (Geschlossen). Regel wie im Postfach der App.",
                          "enum": [
                            "needs_reply",
                            "waiting",
                            "snoozed",
                            "done"
                          ]
                        },
                        "followup_scheduled_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Nächstes geplantes Follow-up, falls eines läuft",
                          "format": "date-time"
                        },
                        "state": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Von Hand gepflegte Angaben, null wenn nie etwas gesetzt wurde",
                          "properties": {
                            "status": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Manuell gesetzter Status in der App (Geschlossen, Später, Wieder geöffnet)",
                              "enum": [
                                "done",
                                "snoozed",
                                "open",
                                null
                              ]
                            },
                            "snooze_until": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Bei status snoozed: bis wann die Unterhaltung zurückgestellt ist (ISO 8601, UTC)",
                              "format": "date-time"
                            },
                            "handled_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zeitpunkt der letzten manuellen Änderung",
                              "format": "date-time"
                            },
                            "tags": {
                              "type": "array",
                              "description": "Schlagwörter der Unterhaltung (eigene und übernommene KI-Kategorien)",
                              "items": {
                                "type": "string"
                              }
                            },
                            "sentiment": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Von Hand gesetzte Stimmung",
                              "enum": [
                                "positiv",
                                "neutral",
                                "negativ",
                                null
                              ]
                            }
                          },
                          "additionalProperties": false
                        },
                        "classification": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "KI-Einordnung des Gesprächs. null, wenn der KI-Assistent des Postfachs ausgeschaltet ist oder noch nichts eingeordnet wurde.",
                          "properties": {
                            "category": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "KI-Antwortkategorie, z. B. interesse, question, objection, not_interested"
                            },
                            "subcategory": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Feinere KI-Kategorie, null wenn keine vergeben ist"
                            },
                            "sentiment": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Stimmung laut KI",
                              "enum": [
                                "positiv",
                                "neutral",
                                "negativ",
                                null
                              ]
                            },
                            "stage": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Gesprächsphase laut KI"
                            },
                            "confidence": {
                              "type": [
                                "number",
                                "null"
                              ],
                              "description": "Sicherheit der KI zwischen 0 und 1"
                            },
                            "reasoning": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Begründung der KI für die Einordnung, Freitext auf Deutsch"
                            },
                            "classified_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Zeitpunkt der letzten KI-Einordnung (ISO 8601, UTC)",
                              "format": "date-time"
                            }
                          },
                          "additionalProperties": false
                        },
                        "created_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt, zu dem dealsky die Unterhaltung erstmals gespeichert hat (ISO 8601, UTC)",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Wiedervorlage in einer Woche",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                        "account": {
                          "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                          "name": "Anna Beispiel"
                        },
                        "counterpart": {
                          "name": "Max Mustermann",
                          "profile_url": "https://www.linkedin.com/in/max-mustermann",
                          "lead_id": "5f1e2d3c-4b5a-4968-8776-655443322110"
                        },
                        "last_message": {
                          "at": "2026-10-18T09:41:12.000Z",
                          "direction": "inbound",
                          "preview": "Klingt spannend, wie läuft so ein E..."
                        },
                        "unread_count": 1,
                        "triage": "snoozed",
                        "followup_scheduled_at": null,
                        "state": {
                          "status": "snoozed",
                          "snooze_until": "2026-10-26T08:00:00.000Z",
                          "handled_at": "2026-10-18T10:05:00.000Z",
                          "tags": [
                            "interesse",
                            "Messe"
                          ],
                          "sentiment": null
                        },
                        "classification": {
                          "category": "interesse",
                          "subcategory": null,
                          "sentiment": "positiv",
                          "stage": "soft_pitch",
                          "confidence": 0.86,
                          "reasoning": "Der Kontakt fragt nach dem Ablauf und signalisiert Interesse am Angebot.",
                          "classified_at": "2026-10-18T09:42:03.000Z"
                        },
                        "created_at": "2026-09-02T10:15:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Schließen und verschlagworten",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                        "account": {
                          "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                          "name": "Anna Beispiel"
                        },
                        "counterpart": {
                          "name": "Max Mustermann",
                          "profile_url": "https://www.linkedin.com/in/max-mustermann",
                          "lead_id": "5f1e2d3c-4b5a-4968-8776-655443322110"
                        },
                        "last_message": {
                          "at": "2026-10-18T09:41:12.000Z",
                          "direction": "inbound",
                          "preview": "Klingt spannend, wie läuft so ein E..."
                        },
                        "unread_count": 1,
                        "triage": "done",
                        "followup_scheduled_at": null,
                        "state": {
                          "status": "done",
                          "snooze_until": null,
                          "handled_at": "2026-10-18T10:05:00.000Z",
                          "tags": [
                            "interesse",
                            "Messe"
                          ],
                          "sentiment": "positiv"
                        },
                        "classification": {
                          "category": "interesse",
                          "subcategory": null,
                          "sentiment": "positiv",
                          "stage": "soft_pitch",
                          "confidence": 0.86,
                          "reasoning": "Der Kontakt fragt nach dem Ablauf und signalisiert Interesse am Angebot.",
                          "classified_at": "2026-10-18T09:42:03.000Z"
                        },
                        "created_at": "2026-09-02T10:15:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel3": {
                    "summary": "Ein Schlagwort ergänzen, die übrigen bleiben",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                        "account": {
                          "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                          "name": "Anna Beispiel"
                        },
                        "counterpart": {
                          "name": "Max Mustermann",
                          "profile_url": "https://www.linkedin.com/in/max-mustermann",
                          "lead_id": "5f1e2d3c-4b5a-4968-8776-655443322110"
                        },
                        "last_message": {
                          "at": "2026-10-18T09:41:12.000Z",
                          "direction": "inbound",
                          "preview": "Klingt spannend, wie läuft so ein E..."
                        },
                        "unread_count": 1,
                        "triage": "needs_reply",
                        "followup_scheduled_at": null,
                        "state": {
                          "status": null,
                          "snooze_until": null,
                          "handled_at": "2026-10-17T15:02:00.000Z",
                          "tags": [
                            "interesse",
                            "Messe",
                            "Rückruf"
                          ],
                          "sentiment": null
                        },
                        "classification": {
                          "category": "interesse",
                          "subcategory": null,
                          "sentiment": "positiv",
                          "stage": "soft_pitch",
                          "confidence": 0.86,
                          "reasoning": "Der Kontakt fragt nach dem Ablauf und signalisiert Interesse am Angebot.",
                          "classified_at": "2026-10-18T09:42:03.000Z"
                        },
                        "created_at": "2026-09-02T10:15:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel4": {
                    "summary": "Schlagwort tauschen",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                        "account": {
                          "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                          "name": "Anna Beispiel"
                        },
                        "counterpart": {
                          "name": "Max Mustermann",
                          "profile_url": "https://www.linkedin.com/in/max-mustermann",
                          "lead_id": "5f1e2d3c-4b5a-4968-8776-655443322110"
                        },
                        "last_message": {
                          "at": "2026-10-18T09:41:12.000Z",
                          "direction": "inbound",
                          "preview": "Klingt spannend, wie läuft so ein E..."
                        },
                        "unread_count": 1,
                        "triage": "needs_reply",
                        "followup_scheduled_at": null,
                        "state": {
                          "status": null,
                          "snooze_until": null,
                          "handled_at": "2026-10-17T15:02:00.000Z",
                          "tags": [
                            "interesse",
                            "Rückruf"
                          ],
                          "sentiment": null
                        },
                        "classification": {
                          "category": "interesse",
                          "subcategory": null,
                          "sentiment": "positiv",
                          "stage": "soft_pitch",
                          "confidence": 0.86,
                          "reasoning": "Der Kontakt fragt nach dem Ablauf und signalisiert Interesse am Angebot.",
                          "classified_at": "2026-10-18T09:42:03.000Z"
                        },
                        "created_at": "2026-09-02T10:15:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:inbox",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/inbox/conversations/{chat_id}/messages": {
      "get": {
        "operationId": "listInboxMessages",
        "tags": [
          "Postfach"
        ],
        "summary": "Nachrichten einer Unterhaltung",
        "description": "Der Verlauf einer Unterhaltung, älteste zuerst wie im Postfach der App (order=newest für die neuesten zuerst). Anders als die App, die den Verlauf in einem Stück lädt und bei 1000 Nachrichten abschneidet, blättert die API ohne Grenze. Sichtbar sind wie in der App nur Unterhaltungen von verbundenen LinkedIn-Konten, auf die die Person, die den Key erzeugt hat, im Postfach Zugriff hat (Inhaber und Admins: alle Konten; Mitglieder: die ihnen zugewiesenen). Nur lesend: Die API synchronisiert nichts mit LinkedIn und markiert nichts als gelesen. Anhänge werden nur beschrieben (Art, Typ, Name, Größe, Dauer); die Dateien selbst liefert die API nicht, sie sind im Postfach der App abrufbar. Nachrichten, die LinkedIn als Reaktion schickt (z. B. „reagiert mit 👍“), stehen wie geliefert im Verlauf.\n\n**Berechtigung:** `read:inbox`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "chat_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Unterhaltung",
              "format": "uuid"
            },
            "description": "ID der Unterhaltung"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "oldest (Standard, wie in der App) oder newest",
              "enum": [
                "oldest",
                "newest"
              ]
            },
            "description": "oldest (Standard, wie in der App) oder newest"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
                            "conversation_id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                            "direction": "inbound",
                            "text": "Klingt spannend, wie läuft so ein Erstgespräch bei Ihnen ab?",
                            "type": "text",
                            "transcription": null,
                            "attachments": [],
                            "sent_at": "2026-10-18T09:41:12.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Nachricht",
                            "format": "uuid"
                          },
                          "conversation_id": {
                            "type": "string",
                            "description": "ID der Unterhaltung (chat_id)",
                            "format": "uuid"
                          },
                          "direction": {
                            "type": "string",
                            "description": "inbound = vom Kontakt, outbound = von Ihnen",
                            "enum": [
                              "inbound",
                              "outbound"
                            ]
                          },
                          "text": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Nachrichtentext, null bei reinen Anhängen"
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Art laut LinkedIn, z. B. text oder voice_note"
                          },
                          "transcription": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Abschrift einer Sprachnachricht, sobald vorhanden"
                          },
                          "attachments": {
                            "type": "array",
                            "description": "Anhänge der Nachricht als Beschreibung ohne Download-Adresse, leer ohne Anhang",
                            "items": {
                              "type": "object",
                              "properties": {
                                "index": {
                                  "type": "integer",
                                  "description": "Position des Anhangs in der Nachricht (0 = erster)"
                                },
                                "kind": {
                                  "type": "string",
                                  "description": "audio (auch Sprachnachricht), image, video, shared_post (geteilter LinkedIn-Beitrag) oder file",
                                  "enum": [
                                    "audio",
                                    "image",
                                    "video",
                                    "shared_post",
                                    "file"
                                  ]
                                },
                                "mime_type": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Dateityp (MIME), z. B. image/jpeg, falls LinkedIn einen liefert"
                                },
                                "name": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Dateiname, falls LinkedIn einen liefert"
                                },
                                "size_bytes": {
                                  "type": [
                                    "integer",
                                    "null"
                                  ],
                                  "description": "Dateigröße in Bytes, falls bekannt"
                                },
                                "width": {
                                  "type": [
                                    "integer",
                                    "null"
                                  ],
                                  "description": "Nur Bilder: Breite in Pixeln, falls bekannt"
                                },
                                "height": {
                                  "type": [
                                    "integer",
                                    "null"
                                  ],
                                  "description": "Nur Bilder: Höhe in Pixeln, falls bekannt"
                                },
                                "duration_seconds": {
                                  "type": [
                                    "number",
                                    "null"
                                  ],
                                  "description": "Nur Audio und Video, falls bekannt"
                                },
                                "unavailable": {
                                  "type": "boolean",
                                  "description": "true, wenn LinkedIn den Inhalt nicht mehr liefert (z. B. gelöschter Beitrag)"
                                },
                                "post_url": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Nur shared_post: öffentlicher Link auf den Beitrag bei LinkedIn",
                                  "format": "uri",
                                  "maxLength": 2048
                                }
                              },
                              "additionalProperties": false
                            }
                          },
                          "sent_at": {
                            "type": "string",
                            "description": "Sendezeitpunkt (ISO 8601, UTC)",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "1b2c3d4e-5f60-4718-8293-a4b5c6d7e8f9",
                          "conversation_id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "direction": "outbound",
                          "text": "Hallo Herr Mustermann, danke für die Vernetzung! Darf ich Ihnen kurz zeigen, wie wir Erstgespräche planen?",
                          "type": "text",
                          "transcription": null,
                          "attachments": [],
                          "sent_at": "2026-10-17T15:02:00.000Z"
                        },
                        {
                          "id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
                          "conversation_id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "direction": "inbound",
                          "text": "Klingt spannend, wie läuft so ein Erstgespräch bei Ihnen ab?",
                          "type": "text",
                          "transcription": null,
                          "attachments": [],
                          "sent_at": "2026-10-18T09:41:12.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Sprachnachricht mit Abschrift",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "9a8b7c6d-5e4f-4a3b-9c2d-1e0f9a8b7c6d",
                          "conversation_id": "c4a1e2b3-5d6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "direction": "inbound",
                          "text": null,
                          "type": "voice_note",
                          "transcription": "Hi, ich melde mich nächste Woche nochmal wegen des Termins.",
                          "attachments": [
                            {
                              "index": 0,
                              "kind": "audio",
                              "mime_type": "audio/mp4",
                              "name": null,
                              "size_bytes": 48213,
                              "width": null,
                              "height": null,
                              "duration_seconds": 12,
                              "unavailable": false,
                              "post_url": null
                            }
                          ],
                          "sent_at": "2026-10-18T09:41:12.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:inbox",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/inbox/tags": {
      "get": {
        "operationId": "listInboxTags",
        "tags": [
          "Postfach"
        ],
        "summary": "Schlagwörter des Postfachs",
        "description": "Die Schlagwörter, die der Tag-Picker im Postfach der App anbietet: die eigenen Schlagwörter des Kontos (älteste zuerst) und, nur bei eingeschaltetem KI-Assistenten, die KI-Kategorien. Diese Werte nimmt PATCH /v1/inbox/conversations/{chat_id} in tags und add_tags an, dazu die an einer Unterhaltung schon gespeicherten. Eigene Schlagwörter legt man in der App im Postfach an (Tag hinzufügen, Neuen Tag erstellen).\n\n**Berechtigung:** `read:inbox`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "value": "Messe",
                            "kind": "custom",
                            "label": "Messe"
                          }
                        ],
                        "properties": {
                          "value": {
                            "type": "string",
                            "description": "Wert für tags, add_tags und remove_tags in PATCH /v1/inbox/conversations/{chat_id}"
                          },
                          "kind": {
                            "type": "string",
                            "description": "custom = eigenes Schlagwort des Postfachs, ai = KI-Kategorie",
                            "enum": [
                              "custom",
                              "ai"
                            ]
                          },
                          "label": {
                            "type": "string",
                            "description": "Anzeigename in der App"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "value": "Messe",
                          "kind": "custom",
                          "label": "Messe"
                        },
                        {
                          "value": "Rückruf",
                          "kind": "custom",
                          "label": "Rückruf"
                        },
                        {
                          "value": "interesse",
                          "kind": "ai",
                          "label": "Interesse"
                        },
                        {
                          "value": "meeting_request",
                          "kind": "ai",
                          "label": "Termin-Wunsch"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:inbox",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/inbox/assistants": {
      "get": {
        "operationId": "listInboxAssistants",
        "tags": [
          "Postfach"
        ],
        "summary": "KI-Assistenten des Postfachs",
        "description": "Die Assistenten wie auf der Seite Inbox-Assistent einrichten: Angebot, Preisregel, Material, Einwände, Ziel mit Buchungslink, Ton, No-Gos und eigene Hinweise, dazu Antwort-Modus und die LinkedIn-Konten, für die der Assistent antwortet. Damit weiß ein Agent, wie im Namen des Kunden geantwortet werden soll. Standard-Assistent zuerst, dann die weiteren wie in der App, danach die Kampagnen-Ergänzungen. Nur lesend, kostet nichts. Anlegen, ändern und zuweisen geht nur in der App.\n\nSo setzt dealsky die Antwort zusammen: Für eine Unterhaltung gilt der Assistent ihres LinkedIn-Kontos (sonst der Standard-Assistent). Läuft der Lead in einer Kampagne mit Ergänzung, gehen deren gefüllte Felder vor; Einwände und eigene Hinweise kommen zu denen des Assistenten dazu, Material ersetzt das des Assistenten nur, wenn die Ergänzung welches hat.\n\nMit account_id kommt der Assistent, der für dieses Konto antwortet, mit campaign_id die Ergänzung dieser Kampagne; beide zusammen liefern beide Schichten für eine Unterhaltung. Ein Konto oder eine Kampagne außerhalb des eigenen Zugriffs ergibt 404.\n\nRecht wie die Seite: Assistent einrichten und bearbeiten (`outreach.inbox.assistant`). Inhaber und Admins sehen alle Assistenten; Mitglieder nur die, die für mindestens eines ihrer zugewiesenen LinkedIn-Konten antworten, und nur Kampagnen-Ergänzungen von Kampagnen, die sie sehen (enger als die App, die ihnen alle zeigt). Ist der Assistent für das Konto vom dealsky-Team gesperrt, zeigt die Seite keine Verwaltung und die API nichts.\n\n**Berechtigung:** `read:inbox`\n\n**Recht in dealsky:** `outreach.inbox.assistant` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Assistenten oder nur Kampagnen-Ergänzungen",
              "enum": [
                "assistant",
                "campaign"
              ]
            },
            "description": "Nur Assistenten oder nur Kampagnen-Ergänzungen"
          },
          {
            "name": "account_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Der Assistent, der für dieses LinkedIn-Konto antwortet",
              "format": "uuid"
            },
            "description": "Der Assistent, der für dieses LinkedIn-Konto antwortet"
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Die Ergänzung dieser Kampagne, falls es eine gibt",
              "format": "uuid"
            },
            "description": "Die Ergänzung dieser Kampagne, falls es eine gibt"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "6d1f2e3a-4b5c-4d6e-8f70-81a2b3c4d5e6",
                            "kind": "assistant",
                            "name": "Standard-Assistent",
                            "is_default": true,
                            "campaign": null,
                            "mode": "copilot",
                            "ai_enabled": true,
                            "accounts": [
                              {
                                "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                                "name": "Anna Beispiel",
                                "connection_status": "connected"
                              }
                            ],
                            "briefing": {
                              "anrede": "sie",
                              "offer": "Wir planen für Steuerkanzleien in Bayern zwei bis vier Erstgespräche pro Woche mit Mandanten aus dem Mittelstand, ohne Kaltakquise am Telefon.",
                              "pricing": {
                                "mode": "range",
                                "value": "mittlerer vierstelliger Betrag pro Monat",
                                "note": "Einrichtung einmalig"
                              },
                              "materials": [
                                {
                                  "type": "case_study",
                                  "label": "Fallstudie Kanzlei Huber",
                                  "url": "https://www.beispiel-agentur.de/fallstudie-huber"
                                }
                              ],
                              "objections": [
                                {
                                  "objection": "Wir haben gerade keine Zeit für neue Mandate.",
                                  "answer": "Verständlich. Wir starten mit zwei Terminen im Monat und richten uns nach Ihrer Kapazität."
                                },
                                {
                                  "objection": "Was kostet das?",
                                  "answer": "Das hängt vom Umfang ab, im Gespräch klären wir das in zehn Minuten."
                                }
                              ],
                              "goal": {
                                "type": "meeting",
                                "booking_link": "https://calendly.com/anna-beispiel/erstgespraech",
                                "duration": "20 Minuten",
                                "format": "google_meet",
                                "description": "Kurzes Kennenlernen, ob ein Pilot passt."
                              },
                              "writing_style_learned": true,
                              "tone": "Freundlich, sachlich, kurze Sätze, keine Emojis.",
                              "no_gos": "Keine Garantien für Umsatz oder Mandantenzahl versprechen.",
                              "custom_notes": "Bei Fragen zu Datenschutz auf den AV-Vertrag verweisen."
                            },
                            "updated_at": "2026-10-12T14:05:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Assistenten oder der Kampagnen-Ergänzung",
                            "format": "uuid"
                          },
                          "kind": {
                            "type": "string",
                            "description": "assistant: ein Assistent, der für LinkedIn-Konten antwortet. campaign: Ergänzung für Unterhaltungen mit Leads einer Kampagne",
                            "enum": [
                              "assistant",
                              "campaign"
                            ]
                          },
                          "name": {
                            "type": "string",
                            "description": "Wie auf der Seite: Standard-Assistent, der eigene Name, bei Kampagnen der Kampagnenname"
                          },
                          "is_default": {
                            "type": "boolean",
                            "description": "Standard-Assistent: antwortet für alle Konten ohne eigenen Assistenten"
                          },
                          "campaign": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Nur bei kind campaign",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "ID der Kampagne (GET /v1/campaigns/{id})",
                                "format": "uuid"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name der Kampagne, null wenn sie keinen hat"
                              }
                            },
                            "additionalProperties": false
                          },
                          "mode": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Antwort-Modus wie auf der Karte: manual (Vorschläge nur auf Klick) oder copilot (bei jeder neuen Antwort bereitet die App automatisch einen Vorschlag vor, 1 Credit je Vorschlag; gesendet wird nur per Klick). Bei Kampagnen-Ergänzungen null, dort gilt der Modus des Assistenten",
                            "enum": [
                              "manual",
                              "copilot",
                              null
                            ]
                          },
                          "ai_enabled": {
                            "type": "boolean",
                            "description": "Schalter KI-Assistent oben auf der Seite, gilt für das ganze Konto und ist bei allen Einträgen gleich. false: kein Assistent arbeitet, keine Einordnung und keine Vorschläge"
                          },
                          "accounts": {
                            "type": "array",
                            "description": "LinkedIn-Konten, für die dieser Assistent antwortet (nur die, auf die die Person mit dem Key Zugriff hat). Bei Kampagnen-Ergänzungen leer",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "description": "LinkedIn-Konto (GET /v1/linkedin/accounts/{id})",
                                  "format": "uuid"
                                },
                                "name": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Anzeigename des LinkedIn-Kontos in dealsky"
                                },
                                "connection_status": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Auch nicht verbundene Konten stehen hier, wie in der App",
                                  "enum": [
                                    "connected",
                                    "pending_verification",
                                    "broken",
                                    "disconnected",
                                    "error",
                                    "reconnecting",
                                    null
                                  ]
                                }
                              },
                              "additionalProperties": false
                            }
                          },
                          "briefing": {
                            "type": "object",
                            "description": "Inhalt des Briefings, wie ihn der Antwort-Agent liest. Felder ohne Eintrag sind null bzw. leer",
                            "properties": {
                              "anrede": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "du oder sie durchgängig. null: nicht festgelegt, die KI leitet die Ansprache aus dem Gesprächsverlauf ab (die Seite zeigt dann Du)",
                                "enum": [
                                  "du",
                                  "sie",
                                  null
                                ]
                              },
                              "offer": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Angebot: was angeboten wird und welcher Nutzen"
                              },
                              "pricing": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "description": "Umgang mit Preisfragen. Ein Preis wird nur auf ausdrückliche Nachfrage des Kontakts genannt, nie von sich aus. null: nichts hinterlegt, die KI nennt dann keine Zahl (die Seite zeigt Nur im Gespräch)",
                                "properties": {
                                  "mode": {
                                    "type": "string",
                                    "description": "range: grober Rahmen, exact: konkreter Preis, after_call: nur im Gespräch, keine Zahl",
                                    "enum": [
                                      "range",
                                      "exact",
                                      "after_call"
                                    ]
                                  },
                                  "value": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Preisangabe bei range und exact, bei after_call immer null"
                                  },
                                  "note": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Zusatz, z. B. einmalige Einrichtung"
                                  }
                                },
                                "additionalProperties": false
                              },
                              "materials": {
                                "type": "array",
                                "description": "Material, das angeboten werden darf. Leer: kein Material, der Assistent verweist auf Erfahrung statt auf Unterlagen",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "type": {
                                      "type": "string",
                                      "description": "loom (Video), case_study (Fallstudie oder PDF), testimonial, landingpage, other",
                                      "enum": [
                                        "loom",
                                        "case_study",
                                        "testimonial",
                                        "landingpage",
                                        "other"
                                      ]
                                    },
                                    "label": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Bezeichnung des Materials, wie auf der Seite eingetragen"
                                    },
                                    "url": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Link, den der Assistent so an Kontakte weitergibt"
                                    }
                                  },
                                  "additionalProperties": false
                                }
                              },
                              "objections": {
                                "type": "array",
                                "description": "Hinterlegte Einwände mit Antwort, leer wenn keine hinterlegt sind",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "objection": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Typischer Einwand"
                                    },
                                    "answer": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "description": "Gewünschte Antwort darauf"
                                    }
                                  },
                                  "additionalProperties": false
                                }
                              },
                              "goal": {
                                "type": [
                                  "object",
                                  "null"
                                ],
                                "description": "Ziel des Gesprächs. null: keins hinterlegt",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "description": "meeting: Termin buchen, send: etwas zuschicken, custom: eigenes Ziel",
                                    "enum": [
                                      "meeting",
                                      "send",
                                      "custom"
                                    ]
                                  },
                                  "booking_link": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Nur meeting: Kalender-Link, den der Assistent unverändert mitschickt"
                                  },
                                  "duration": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Nur meeting: Dauer, z. B. 20 Minuten"
                                  },
                                  "format": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Nur meeting: telefon, zoom, google_meet, teams, vor_ort oder flexibel",
                                    "enum": [
                                      "telefon",
                                      "zoom",
                                      "google_meet",
                                      "teams",
                                      "vor_ort",
                                      "flexibel",
                                      null
                                    ]
                                  },
                                  "description": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Beschreibung des Ziels bzw. was verschickt wird"
                                  }
                                },
                                "additionalProperties": false
                              },
                              "writing_style_learned": {
                                "type": [
                                  "boolean",
                                  "null"
                                ],
                                "description": "Hat der Assistent den Schreibstil aus echten Nachrichten gelernt? Den Stil selbst gibt die API nicht heraus. Bei Kampagnen-Ergänzungen null (der Stil gehört zum Assistenten)"
                              },
                              "tone": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Ton und Persona"
                              },
                              "no_gos": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Was nie gesagt oder versprochen werden darf"
                              },
                              "custom_notes": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Eigene Hinweise"
                              }
                            },
                            "additionalProperties": false
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzte Änderung des Briefings (ISO 8601, UTC)",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Alle Assistenten",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "6d1f2e3a-4b5c-4d6e-8f70-81a2b3c4d5e6",
                          "kind": "assistant",
                          "name": "Standard-Assistent",
                          "is_default": true,
                          "campaign": null,
                          "mode": "copilot",
                          "ai_enabled": true,
                          "accounts": [
                            {
                              "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                              "name": "Anna Beispiel",
                              "connection_status": "connected"
                            }
                          ],
                          "briefing": {
                            "anrede": "sie",
                            "offer": "Wir planen für Steuerkanzleien in Bayern zwei bis vier Erstgespräche pro Woche mit Mandanten aus dem Mittelstand, ohne Kaltakquise am Telefon.",
                            "pricing": {
                              "mode": "range",
                              "value": "mittlerer vierstelliger Betrag pro Monat",
                              "note": "Einrichtung einmalig"
                            },
                            "materials": [
                              {
                                "type": "case_study",
                                "label": "Fallstudie Kanzlei Huber",
                                "url": "https://www.beispiel-agentur.de/fallstudie-huber"
                              }
                            ],
                            "objections": [
                              {
                                "objection": "Wir haben gerade keine Zeit für neue Mandate.",
                                "answer": "Verständlich. Wir starten mit zwei Terminen im Monat und richten uns nach Ihrer Kapazität."
                              },
                              {
                                "objection": "Was kostet das?",
                                "answer": "Das hängt vom Umfang ab, im Gespräch klären wir das in zehn Minuten."
                              }
                            ],
                            "goal": {
                              "type": "meeting",
                              "booking_link": "https://calendly.com/anna-beispiel/erstgespraech",
                              "duration": "20 Minuten",
                              "format": "google_meet",
                              "description": "Kurzes Kennenlernen, ob ein Pilot passt."
                            },
                            "writing_style_learned": true,
                            "tone": "Freundlich, sachlich, kurze Sätze, keine Emojis.",
                            "no_gos": "Keine Garantien für Umsatz oder Mandantenzahl versprechen.",
                            "custom_notes": "Bei Fragen zu Datenschutz auf den AV-Vertrag verweisen."
                          },
                          "updated_at": "2026-10-12T14:05:00.000Z"
                        },
                        {
                          "id": "9e8d7c6b-5a49-4f38-8a27-16f5e4d3c2b1",
                          "kind": "campaign",
                          "name": "Messe Steuerberatertag 2026",
                          "is_default": false,
                          "campaign": {
                            "id": "3c2b1a09-8f7e-4d6c-9b5a-493827160f5e",
                            "name": "Messe Steuerberatertag 2026"
                          },
                          "mode": null,
                          "ai_enabled": true,
                          "accounts": [],
                          "briefing": {
                            "anrede": null,
                            "offer": "Nachbesprechung vom Steuerberatertag: Messe-Angebot mit 20 Prozent Rabatt im ersten Quartal.",
                            "pricing": null,
                            "materials": [],
                            "objections": [],
                            "goal": null,
                            "writing_style_learned": null,
                            "tone": null,
                            "no_gos": null,
                            "custom_notes": "Auf das Gespräch am Stand Bezug nehmen."
                          },
                          "updated_at": "2026-10-15T09:30:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Was für eine Unterhaltung gilt (Konto und Kampagne)",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "6d1f2e3a-4b5c-4d6e-8f70-81a2b3c4d5e6",
                          "kind": "assistant",
                          "name": "Standard-Assistent",
                          "is_default": true,
                          "campaign": null,
                          "mode": "copilot",
                          "ai_enabled": true,
                          "accounts": [
                            {
                              "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                              "name": "Anna Beispiel",
                              "connection_status": "connected"
                            }
                          ],
                          "briefing": {
                            "anrede": "sie",
                            "offer": "Wir planen für Steuerkanzleien in Bayern zwei bis vier Erstgespräche pro Woche mit Mandanten aus dem Mittelstand, ohne Kaltakquise am Telefon.",
                            "pricing": {
                              "mode": "range",
                              "value": "mittlerer vierstelliger Betrag pro Monat",
                              "note": "Einrichtung einmalig"
                            },
                            "materials": [
                              {
                                "type": "case_study",
                                "label": "Fallstudie Kanzlei Huber",
                                "url": "https://www.beispiel-agentur.de/fallstudie-huber"
                              }
                            ],
                            "objections": [
                              {
                                "objection": "Wir haben gerade keine Zeit für neue Mandate.",
                                "answer": "Verständlich. Wir starten mit zwei Terminen im Monat und richten uns nach Ihrer Kapazität."
                              },
                              {
                                "objection": "Was kostet das?",
                                "answer": "Das hängt vom Umfang ab, im Gespräch klären wir das in zehn Minuten."
                              }
                            ],
                            "goal": {
                              "type": "meeting",
                              "booking_link": "https://calendly.com/anna-beispiel/erstgespraech",
                              "duration": "20 Minuten",
                              "format": "google_meet",
                              "description": "Kurzes Kennenlernen, ob ein Pilot passt."
                            },
                            "writing_style_learned": true,
                            "tone": "Freundlich, sachlich, kurze Sätze, keine Emojis.",
                            "no_gos": "Keine Garantien für Umsatz oder Mandantenzahl versprechen.",
                            "custom_notes": "Bei Fragen zu Datenschutz auf den AV-Vertrag verweisen."
                          },
                          "updated_at": "2026-10-12T14:05:00.000Z"
                        },
                        {
                          "id": "9e8d7c6b-5a49-4f38-8a27-16f5e4d3c2b1",
                          "kind": "campaign",
                          "name": "Messe Steuerberatertag 2026",
                          "is_default": false,
                          "campaign": {
                            "id": "3c2b1a09-8f7e-4d6c-9b5a-493827160f5e",
                            "name": "Messe Steuerberatertag 2026"
                          },
                          "mode": null,
                          "ai_enabled": true,
                          "accounts": [],
                          "briefing": {
                            "anrede": null,
                            "offer": "Nachbesprechung vom Steuerberatertag: Messe-Angebot mit 20 Prozent Rabatt im ersten Quartal.",
                            "pricing": null,
                            "materials": [],
                            "objections": [],
                            "goal": null,
                            "writing_style_learned": null,
                            "tone": null,
                            "no_gos": null,
                            "custom_notes": "Auf das Gespräch am Stand Bezug nehmen."
                          },
                          "updated_at": "2026-10-15T09:30:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:inbox",
        "x-dealsky-permission": "outreach.inbox.assistant",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/inbox/assistants/{id}": {
      "get": {
        "operationId": "getInboxAssistant",
        "tags": [
          "Postfach"
        ],
        "summary": "Ein KI-Assistent",
        "description": "Dieselben Angaben wie in der Liste, für einen Assistenten oder eine Kampagnen-Ergänzung. Recht wie die Seite: Assistent einrichten und bearbeiten (`outreach.inbox.assistant`). Inhaber und Admins sehen alle Assistenten; Mitglieder nur die, die für mindestens eines ihrer zugewiesenen LinkedIn-Konten antworten, und nur Kampagnen-Ergänzungen von Kampagnen, die sie sehen (enger als die App, die ihnen alle zeigt). Ist der Assistent für das Konto vom dealsky-Team gesperrt, zeigt die Seite keine Verwaltung und die API nichts. Eine ID außerhalb davon ergibt 404. Kostet nichts.\n\n**Berechtigung:** `read:inbox`\n\n**Recht in dealsky:** `outreach.inbox.assistant` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Assistenten oder der Kampagnen-Ergänzung",
              "format": "uuid"
            },
            "description": "ID des Assistenten oder der Kampagnen-Ergänzung"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6d1f2e3a-4b5c-4d6e-8f70-81a2b3c4d5e6",
                          "kind": "assistant",
                          "name": "Standard-Assistent",
                          "is_default": true,
                          "campaign": null,
                          "mode": "copilot",
                          "ai_enabled": true,
                          "accounts": [
                            {
                              "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                              "name": "Anna Beispiel",
                              "connection_status": "connected"
                            }
                          ],
                          "briefing": {
                            "anrede": "sie",
                            "offer": "Wir planen für Steuerkanzleien in Bayern zwei bis vier Erstgespräche pro Woche mit Mandanten aus dem Mittelstand, ohne Kaltakquise am Telefon.",
                            "pricing": {
                              "mode": "range",
                              "value": "mittlerer vierstelliger Betrag pro Monat",
                              "note": "Einrichtung einmalig"
                            },
                            "materials": [
                              {
                                "type": "case_study",
                                "label": "Fallstudie Kanzlei Huber",
                                "url": "https://www.beispiel-agentur.de/fallstudie-huber"
                              }
                            ],
                            "objections": [
                              {
                                "objection": "Wir haben gerade keine Zeit für neue Mandate.",
                                "answer": "Verständlich. Wir starten mit zwei Terminen im Monat und richten uns nach Ihrer Kapazität."
                              },
                              {
                                "objection": "Was kostet das?",
                                "answer": "Das hängt vom Umfang ab, im Gespräch klären wir das in zehn Minuten."
                              }
                            ],
                            "goal": {
                              "type": "meeting",
                              "booking_link": "https://calendly.com/anna-beispiel/erstgespraech",
                              "duration": "20 Minuten",
                              "format": "google_meet",
                              "description": "Kurzes Kennenlernen, ob ein Pilot passt."
                            },
                            "writing_style_learned": true,
                            "tone": "Freundlich, sachlich, kurze Sätze, keine Emojis.",
                            "no_gos": "Keine Garantien für Umsatz oder Mandantenzahl versprechen.",
                            "custom_notes": "Bei Fragen zu Datenschutz auf den AV-Vertrag verweisen."
                          },
                          "updated_at": "2026-10-12T14:05:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Assistenten oder der Kampagnen-Ergänzung",
                          "format": "uuid"
                        },
                        "kind": {
                          "type": "string",
                          "description": "assistant: ein Assistent, der für LinkedIn-Konten antwortet. campaign: Ergänzung für Unterhaltungen mit Leads einer Kampagne",
                          "enum": [
                            "assistant",
                            "campaign"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "description": "Wie auf der Seite: Standard-Assistent, der eigene Name, bei Kampagnen der Kampagnenname"
                        },
                        "is_default": {
                          "type": "boolean",
                          "description": "Standard-Assistent: antwortet für alle Konten ohne eigenen Assistenten"
                        },
                        "campaign": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Nur bei kind campaign",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "ID der Kampagne (GET /v1/campaigns/{id})",
                              "format": "uuid"
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Name der Kampagne, null wenn sie keinen hat"
                            }
                          },
                          "additionalProperties": false
                        },
                        "mode": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Antwort-Modus wie auf der Karte: manual (Vorschläge nur auf Klick) oder copilot (bei jeder neuen Antwort bereitet die App automatisch einen Vorschlag vor, 1 Credit je Vorschlag; gesendet wird nur per Klick). Bei Kampagnen-Ergänzungen null, dort gilt der Modus des Assistenten",
                          "enum": [
                            "manual",
                            "copilot",
                            null
                          ]
                        },
                        "ai_enabled": {
                          "type": "boolean",
                          "description": "Schalter KI-Assistent oben auf der Seite, gilt für das ganze Konto und ist bei allen Einträgen gleich. false: kein Assistent arbeitet, keine Einordnung und keine Vorschläge"
                        },
                        "accounts": {
                          "type": "array",
                          "description": "LinkedIn-Konten, für die dieser Assistent antwortet (nur die, auf die die Person mit dem Key Zugriff hat). Bei Kampagnen-Ergänzungen leer",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "LinkedIn-Konto (GET /v1/linkedin/accounts/{id})",
                                "format": "uuid"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Anzeigename des LinkedIn-Kontos in dealsky"
                              },
                              "connection_status": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Auch nicht verbundene Konten stehen hier, wie in der App",
                                "enum": [
                                  "connected",
                                  "pending_verification",
                                  "broken",
                                  "disconnected",
                                  "error",
                                  "reconnecting",
                                  null
                                ]
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "briefing": {
                          "type": "object",
                          "description": "Inhalt des Briefings, wie ihn der Antwort-Agent liest. Felder ohne Eintrag sind null bzw. leer",
                          "properties": {
                            "anrede": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "du oder sie durchgängig. null: nicht festgelegt, die KI leitet die Ansprache aus dem Gesprächsverlauf ab (die Seite zeigt dann Du)",
                              "enum": [
                                "du",
                                "sie",
                                null
                              ]
                            },
                            "offer": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Angebot: was angeboten wird und welcher Nutzen"
                            },
                            "pricing": {
                              "type": [
                                "object",
                                "null"
                              ],
                              "description": "Umgang mit Preisfragen. Ein Preis wird nur auf ausdrückliche Nachfrage des Kontakts genannt, nie von sich aus. null: nichts hinterlegt, die KI nennt dann keine Zahl (die Seite zeigt Nur im Gespräch)",
                              "properties": {
                                "mode": {
                                  "type": "string",
                                  "description": "range: grober Rahmen, exact: konkreter Preis, after_call: nur im Gespräch, keine Zahl",
                                  "enum": [
                                    "range",
                                    "exact",
                                    "after_call"
                                  ]
                                },
                                "value": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Preisangabe bei range und exact, bei after_call immer null"
                                },
                                "note": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Zusatz, z. B. einmalige Einrichtung"
                                }
                              },
                              "additionalProperties": false
                            },
                            "materials": {
                              "type": "array",
                              "description": "Material, das angeboten werden darf. Leer: kein Material, der Assistent verweist auf Erfahrung statt auf Unterlagen",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "description": "loom (Video), case_study (Fallstudie oder PDF), testimonial, landingpage, other",
                                    "enum": [
                                      "loom",
                                      "case_study",
                                      "testimonial",
                                      "landingpage",
                                      "other"
                                    ]
                                  },
                                  "label": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Bezeichnung des Materials, wie auf der Seite eingetragen"
                                  },
                                  "url": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Link, den der Assistent so an Kontakte weitergibt"
                                  }
                                },
                                "additionalProperties": false
                              }
                            },
                            "objections": {
                              "type": "array",
                              "description": "Hinterlegte Einwände mit Antwort, leer wenn keine hinterlegt sind",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "objection": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Typischer Einwand"
                                  },
                                  "answer": {
                                    "type": [
                                      "string",
                                      "null"
                                    ],
                                    "description": "Gewünschte Antwort darauf"
                                  }
                                },
                                "additionalProperties": false
                              }
                            },
                            "goal": {
                              "type": [
                                "object",
                                "null"
                              ],
                              "description": "Ziel des Gesprächs. null: keins hinterlegt",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "description": "meeting: Termin buchen, send: etwas zuschicken, custom: eigenes Ziel",
                                  "enum": [
                                    "meeting",
                                    "send",
                                    "custom"
                                  ]
                                },
                                "booking_link": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Nur meeting: Kalender-Link, den der Assistent unverändert mitschickt"
                                },
                                "duration": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Nur meeting: Dauer, z. B. 20 Minuten"
                                },
                                "format": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Nur meeting: telefon, zoom, google_meet, teams, vor_ort oder flexibel",
                                  "enum": [
                                    "telefon",
                                    "zoom",
                                    "google_meet",
                                    "teams",
                                    "vor_ort",
                                    "flexibel",
                                    null
                                  ]
                                },
                                "description": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Beschreibung des Ziels bzw. was verschickt wird"
                                }
                              },
                              "additionalProperties": false
                            },
                            "writing_style_learned": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "Hat der Assistent den Schreibstil aus echten Nachrichten gelernt? Den Stil selbst gibt die API nicht heraus. Bei Kampagnen-Ergänzungen null (der Stil gehört zum Assistenten)"
                            },
                            "tone": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ton und Persona"
                            },
                            "no_gos": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Was nie gesagt oder versprochen werden darf"
                            },
                            "custom_notes": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Eigene Hinweise"
                            }
                          },
                          "additionalProperties": false
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte Änderung des Briefings (ISO 8601, UTC)",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6d1f2e3a-4b5c-4d6e-8f70-81a2b3c4d5e6",
                        "kind": "assistant",
                        "name": "Standard-Assistent",
                        "is_default": true,
                        "campaign": null,
                        "mode": "copilot",
                        "ai_enabled": true,
                        "accounts": [
                          {
                            "id": "7b2d9c41-3e5f-4a68-9b1c-2d3e4f5a6b7c",
                            "name": "Anna Beispiel",
                            "connection_status": "connected"
                          }
                        ],
                        "briefing": {
                          "anrede": "sie",
                          "offer": "Wir planen für Steuerkanzleien in Bayern zwei bis vier Erstgespräche pro Woche mit Mandanten aus dem Mittelstand, ohne Kaltakquise am Telefon.",
                          "pricing": {
                            "mode": "range",
                            "value": "mittlerer vierstelliger Betrag pro Monat",
                            "note": "Einrichtung einmalig"
                          },
                          "materials": [
                            {
                              "type": "case_study",
                              "label": "Fallstudie Kanzlei Huber",
                              "url": "https://www.beispiel-agentur.de/fallstudie-huber"
                            }
                          ],
                          "objections": [
                            {
                              "objection": "Wir haben gerade keine Zeit für neue Mandate.",
                              "answer": "Verständlich. Wir starten mit zwei Terminen im Monat und richten uns nach Ihrer Kapazität."
                            },
                            {
                              "objection": "Was kostet das?",
                              "answer": "Das hängt vom Umfang ab, im Gespräch klären wir das in zehn Minuten."
                            }
                          ],
                          "goal": {
                            "type": "meeting",
                            "booking_link": "https://calendly.com/anna-beispiel/erstgespraech",
                            "duration": "20 Minuten",
                            "format": "google_meet",
                            "description": "Kurzes Kennenlernen, ob ein Pilot passt."
                          },
                          "writing_style_learned": true,
                          "tone": "Freundlich, sachlich, kurze Sätze, keine Emojis.",
                          "no_gos": "Keine Garantien für Umsatz oder Mandantenzahl versprechen.",
                          "custom_notes": "Bei Fragen zu Datenschutz auf den AV-Vertrag verweisen."
                        },
                        "updated_at": "2026-10-12T14:05:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:inbox",
        "x-dealsky-permission": "outreach.inbox.assistant",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/landing-page-templates": {
      "get": {
        "operationId": "listLandingPageTemplates",
        "tags": [
          "Landingpages"
        ],
        "summary": "Landingpage-Vorlagen auflisten",
        "description": "Die Vorlagen, die in dealsky unter Assets, Landingpages stehen und in Kampagnen wählbar sind (status active), neueste zuerst. Ohne den Aufbau der Seite; den liefert der Abruf einer einzelnen Vorlage.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Suche im Namen (Teilstring, Groß/Klein egal)",
              "maxLength": 200
            },
            "description": "Suche im Namen (Teilstring, Groß/Klein egal)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                            "name": "Outreach Geschäftsführer",
                            "description": null,
                            "status": "active",
                            "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                            "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                            "created_at": "2026-09-02T10:15:00.000Z",
                            "updated_at": "2026-10-14T16:40:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der Vorlage (template_id bei den persönlichen Seiten)",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name der Vorlage wie in der App"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Beschreibung der Vorlage, null wenn keine hinterlegt ist"
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "active = in Kampagnen und im Impact Studio wählbar"
                          },
                          "thumbnail_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vorschaubild der Vorlage"
                          },
                          "preview_url": {
                            "type": "string",
                            "description": "Vorschau mit Beispiel-Lead in dealsky (braucht eine Anmeldung in dealsky). Vorlagen selbst haben keine öffentliche Adresse."
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Anlagezeitpunkt der Vorlage (ISO 8601, UTC)",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzte Änderung der Vorlage (ISO 8601, UTC)",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "name": "Outreach Geschäftsführer",
                          "description": null,
                          "status": "active",
                          "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                          "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "created_at": "2026-09-02T10:15:00.000Z",
                          "updated_at": "2026-10-14T16:40:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/landing-page-templates/{id}": {
      "get": {
        "operationId": "getLandingPageTemplate",
        "tags": [
          "Landingpages"
        ],
        "summary": "Eine Landingpage-Vorlage abrufen",
        "description": "Mit dem Aufbau der Seite (Abschnitte, Blocktypen, Buchungs- und Danke-Seite, Art des Videos) und der Zahl der daraus erzeugten persönlichen Seiten. Texte, Farben und Stile aus dem Editor gibt die API nicht heraus. Gelöschte Vorlagen antworten 404.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Vorlage",
              "format": "uuid"
            },
            "description": "ID der Vorlage"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "name": "Outreach Geschäftsführer",
                          "description": null,
                          "status": "active",
                          "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                          "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "created_at": "2026-09-02T10:15:00.000Z",
                          "updated_at": "2026-10-14T16:40:00.000Z",
                          "structure": {
                            "layout": "variant1",
                            "sections": [
                              "comparison",
                              "cta",
                              "approach",
                              "finalCta"
                            ],
                            "hidden_sections": [
                              "faq"
                            ],
                            "blocks": [
                              {
                                "type": "text",
                                "count": 2
                              },
                              {
                                "type": "testimonial",
                                "count": 1
                              }
                            ],
                            "booking_page_blocks": [
                              "heading",
                              "calendar_embed"
                            ],
                            "thank_you_page_blocks": [
                              "heading",
                              "text"
                            ],
                            "hero_video_type": "personalized",
                            "external_cta_url": null,
                            "seo_title": "Ein Video für {{first_name}}",
                            "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                          },
                          "landing_pages_count": 42
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Vorlage (template_id bei den persönlichen Seiten)",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Vorlage wie in der App"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Beschreibung der Vorlage, null wenn keine hinterlegt ist"
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "active = in Kampagnen und im Impact Studio wählbar"
                        },
                        "thumbnail_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorschaubild der Vorlage"
                        },
                        "preview_url": {
                          "type": "string",
                          "description": "Vorschau mit Beispiel-Lead in dealsky (braucht eine Anmeldung in dealsky). Vorlagen selbst haben keine öffentliche Adresse."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Anlagezeitpunkt der Vorlage (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte Änderung der Vorlage (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "structure": {
                          "type": "object",
                          "description": "Aufbau der Vorlage ohne Editor-Daten (Texte, Farben, Stile): Abschnitte, Blöcke, Video-Art, SEO-Angaben",
                          "properties": {
                            "layout": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Grundaufbau: variant1 oder variant2"
                            },
                            "sections": {
                              "type": [
                                "array",
                                "null"
                              ],
                              "description": "Sichtbare Abschnitte unter dem Kopfbereich mit Video in ihrer Reihenfolge, z. B. comparison, cta, approach, faq, finalCta. null = Standardreihenfolge der Vorlage",
                              "items": {
                                "type": "string"
                              }
                            },
                            "hidden_sections": {
                              "type": "array",
                              "description": "Ausgeblendete Abschnitte",
                              "items": {
                                "type": "string"
                              }
                            },
                            "blocks": {
                              "type": "array",
                              "description": "Zusätzliche Blöcke auf der Hauptseite je Typ",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "description": "Blocktyp, z. B. text, image, explainer_video, video_personalized, calendar_embed, testimonial"
                                  },
                                  "count": {
                                    "type": "integer",
                                    "description": "Anzahl Blöcke dieses Typs"
                                  }
                                },
                                "additionalProperties": false
                              }
                            },
                            "booking_page_blocks": {
                              "type": "array",
                              "description": "Blocktypen der Buchungsseite. Leer, wenn ein externer CTA-Link aktiv ist.",
                              "items": {
                                "type": "string"
                              }
                            },
                            "thank_you_page_blocks": {
                              "type": "array",
                              "description": "Blocktypen der Danke-Seite. Leer, wenn ein externer CTA-Link aktiv ist.",
                              "items": {
                                "type": "string"
                              }
                            },
                            "hero_video_type": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "personalized = je Lead ein eigenes Video, static = dasselbe Video für alle"
                            },
                            "external_cta_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ziel der Buttons, wenn sie auf eine externe Seite statt auf die Buchungsseite führen"
                            },
                            "seo_title": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Titel für Suchmaschinen und Link-Vorschau, Platzhalter wie {{first_name}} werden je Lead ersetzt"
                            },
                            "seo_description": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Beschreibung für Suchmaschinen und Link-Vorschau, null wenn keine hinterlegt ist"
                            }
                          },
                          "additionalProperties": false
                        },
                        "landing_pages_count": {
                          "type": "integer",
                          "description": "Persönliche Landingpages, die aus dieser Vorlage erzeugt wurden"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "name": "Outreach Geschäftsführer",
                        "description": null,
                        "status": "active",
                        "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                        "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "created_at": "2026-09-02T10:15:00.000Z",
                        "updated_at": "2026-10-14T16:40:00.000Z",
                        "structure": {
                          "layout": "variant1",
                          "sections": [
                            "comparison",
                            "cta",
                            "approach",
                            "finalCta"
                          ],
                          "hidden_sections": [
                            "faq"
                          ],
                          "blocks": [
                            {
                              "type": "text",
                              "count": 2
                            },
                            {
                              "type": "testimonial",
                              "count": 1
                            }
                          ],
                          "booking_page_blocks": [
                            "heading",
                            "calendar_embed"
                          ],
                          "thank_you_page_blocks": [
                            "heading",
                            "text"
                          ],
                          "hero_video_type": "personalized",
                          "external_cta_url": null,
                          "seo_title": "Ein Video für {{first_name}}",
                          "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                        },
                        "landing_pages_count": 42
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read"
      },
      "patch": {
        "operationId": "updateLandingPageTemplate",
        "tags": [
          "Landingpages"
        ],
        "summary": "Landingpage-Vorlage umbenennen, SEO-Titel und -Beschreibung ändern",
        "description": "Ändert, was die App im Landingpage-Editor außerhalb der Blöcke ändert: den Namen und den SEO-Titel und die SEO-Beschreibung (Bereich SEO im Design). Texte, Blöcke, Design, Video und Kalender ändert die API nicht; dafür gibt es den Editor in dealsky. Aktivieren und Deaktivieren gibt es in der App nicht, darum auch nicht hier (Löschen: `DELETE`). Nur übergebene Felder werden geändert; Werte, die schon so gespeichert sind, schreiben nichts.\n\n**Wirkung:** Der Name ist nur Anzeige. Ein neuer SEO-Titel gilt für Seiten, die ab jetzt aus der Vorlage erzeugt werden, auch in laufenden Kampagnen. Bereits erzeugte persönliche Seiten behalten ihren Titel, weil die Vorlage beim Erzeugen kopiert wird. Den Abgleich mit vorhandenen Seiten bietet die App nur an, wenn der Titel im Editor geändert wird.\n\n**Gleichzeitige Bearbeitung:** Der Editor der App speichert immer die ganze Seite. Ist die Vorlage gerade in dealsky geöffnet, überschreibt das nächste Speichern dort diese Änderung. Beim SEO-Titel und der SEO-Beschreibung schreibt die API die Seite nur, wenn sie sich seit dem Lesen nicht geändert hat, sonst antwortet sie 409 mit `details.reason = concurrent_update`; dann einfach erneut senden.\n\nDie Antwort hat das Format von `GET /v1/landing-page-templates/{id}`. Gelöschte oder fremde Vorlagen antworten 404. Fehlt der Vorlage das Design (nie im Editor gespeichert), lässt sich der SEO-Titel nicht setzen: 422 mit `details.reason = invalid_template`.\n\n**Berechtigung:** `write:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Vorlage",
              "format": "uuid"
            },
            "description": "ID der Vorlage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name der Vorlage, wie unter Assets, Landingpages angezeigt, muss nicht eindeutig sein",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "seo_title": {
                    "type": "string",
                    "description": "Seitentitel für Suchmaschinen und Link-Vorschau (structure.seo_title). Platzhalter wie {{first_name}} werden je Lead ersetzt",
                    "maxLength": 300
                  },
                  "seo_description": {
                    "type": "string",
                    "description": "Beschreibung für Suchmaschinen und Link-Vorschau (structure.seo_description), ebenfalls mit Platzhaltern",
                    "maxLength": 1000
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Umbenennen",
                  "value": {
                    "name": "Outreach Geschäftsführer Herbst"
                  }
                },
                "beispiel2": {
                  "summary": "SEO-Titel ändern",
                  "value": {
                    "name": "Outreach Geschäftsführer Herbst",
                    "seo_title": "{{first_name}}, ein Video nur für Sie"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "name": "Outreach Geschäftsführer",
                          "description": null,
                          "status": "active",
                          "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                          "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "created_at": "2026-09-02T10:15:00.000Z",
                          "updated_at": "2026-10-14T16:40:00.000Z",
                          "structure": {
                            "layout": "variant1",
                            "sections": [
                              "comparison",
                              "cta",
                              "approach",
                              "finalCta"
                            ],
                            "hidden_sections": [
                              "faq"
                            ],
                            "blocks": [
                              {
                                "type": "text",
                                "count": 2
                              },
                              {
                                "type": "testimonial",
                                "count": 1
                              }
                            ],
                            "booking_page_blocks": [
                              "heading",
                              "calendar_embed"
                            ],
                            "thank_you_page_blocks": [
                              "heading",
                              "text"
                            ],
                            "hero_video_type": "personalized",
                            "external_cta_url": null,
                            "seo_title": "Ein Video für {{first_name}}",
                            "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                          },
                          "landing_pages_count": 42
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Vorlage (template_id bei den persönlichen Seiten)",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Vorlage wie in der App"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Beschreibung der Vorlage, null wenn keine hinterlegt ist"
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "active = in Kampagnen und im Impact Studio wählbar"
                        },
                        "thumbnail_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorschaubild der Vorlage"
                        },
                        "preview_url": {
                          "type": "string",
                          "description": "Vorschau mit Beispiel-Lead in dealsky (braucht eine Anmeldung in dealsky). Vorlagen selbst haben keine öffentliche Adresse."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Anlagezeitpunkt der Vorlage (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte Änderung der Vorlage (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "structure": {
                          "type": "object",
                          "description": "Aufbau der Vorlage ohne Editor-Daten (Texte, Farben, Stile): Abschnitte, Blöcke, Video-Art, SEO-Angaben",
                          "properties": {
                            "layout": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Grundaufbau: variant1 oder variant2"
                            },
                            "sections": {
                              "type": [
                                "array",
                                "null"
                              ],
                              "description": "Sichtbare Abschnitte unter dem Kopfbereich mit Video in ihrer Reihenfolge, z. B. comparison, cta, approach, faq, finalCta. null = Standardreihenfolge der Vorlage",
                              "items": {
                                "type": "string"
                              }
                            },
                            "hidden_sections": {
                              "type": "array",
                              "description": "Ausgeblendete Abschnitte",
                              "items": {
                                "type": "string"
                              }
                            },
                            "blocks": {
                              "type": "array",
                              "description": "Zusätzliche Blöcke auf der Hauptseite je Typ",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "description": "Blocktyp, z. B. text, image, explainer_video, video_personalized, calendar_embed, testimonial"
                                  },
                                  "count": {
                                    "type": "integer",
                                    "description": "Anzahl Blöcke dieses Typs"
                                  }
                                },
                                "additionalProperties": false
                              }
                            },
                            "booking_page_blocks": {
                              "type": "array",
                              "description": "Blocktypen der Buchungsseite. Leer, wenn ein externer CTA-Link aktiv ist.",
                              "items": {
                                "type": "string"
                              }
                            },
                            "thank_you_page_blocks": {
                              "type": "array",
                              "description": "Blocktypen der Danke-Seite. Leer, wenn ein externer CTA-Link aktiv ist.",
                              "items": {
                                "type": "string"
                              }
                            },
                            "hero_video_type": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "personalized = je Lead ein eigenes Video, static = dasselbe Video für alle"
                            },
                            "external_cta_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ziel der Buttons, wenn sie auf eine externe Seite statt auf die Buchungsseite führen"
                            },
                            "seo_title": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Titel für Suchmaschinen und Link-Vorschau, Platzhalter wie {{first_name}} werden je Lead ersetzt"
                            },
                            "seo_description": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Beschreibung für Suchmaschinen und Link-Vorschau, null wenn keine hinterlegt ist"
                            }
                          },
                          "additionalProperties": false
                        },
                        "landing_pages_count": {
                          "type": "integer",
                          "description": "Persönliche Landingpages, die aus dieser Vorlage erzeugt wurden"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Umbenennen",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "name": "Outreach Geschäftsführer Herbst",
                        "description": null,
                        "status": "active",
                        "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                        "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "created_at": "2026-09-02T10:15:00.000Z",
                        "updated_at": "2026-10-18T09:40:00.000Z",
                        "structure": {
                          "layout": "variant1",
                          "sections": [
                            "comparison",
                            "cta",
                            "approach",
                            "finalCta"
                          ],
                          "hidden_sections": [
                            "faq"
                          ],
                          "blocks": [
                            {
                              "type": "text",
                              "count": 2
                            },
                            {
                              "type": "testimonial",
                              "count": 1
                            }
                          ],
                          "booking_page_blocks": [
                            "heading",
                            "calendar_embed"
                          ],
                          "thank_you_page_blocks": [
                            "heading",
                            "text"
                          ],
                          "hero_video_type": "personalized",
                          "external_cta_url": null,
                          "seo_title": "Ein Video für {{first_name}}",
                          "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                        },
                        "landing_pages_count": 42
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "SEO-Titel ändern",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "name": "Outreach Geschäftsführer Herbst",
                        "description": null,
                        "status": "active",
                        "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                        "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "created_at": "2026-09-02T10:15:00.000Z",
                        "updated_at": "2026-10-18T09:40:00.000Z",
                        "structure": {
                          "layout": "variant1",
                          "sections": [
                            "comparison",
                            "cta",
                            "approach",
                            "finalCta"
                          ],
                          "hidden_sections": [
                            "faq"
                          ],
                          "blocks": [
                            {
                              "type": "text",
                              "count": 2
                            },
                            {
                              "type": "testimonial",
                              "count": 1
                            }
                          ],
                          "booking_page_blocks": [
                            "heading",
                            "calendar_embed"
                          ],
                          "thank_you_page_blocks": [
                            "heading",
                            "text"
                          ],
                          "hero_video_type": "personalized",
                          "external_cta_url": null,
                          "seo_title": "{{first_name}}, ein Video nur für Sie",
                          "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                        },
                        "landing_pages_count": 42
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "write"
      },
      "delete": {
        "operationId": "deleteLandingPageTemplate",
        "tags": [
          "Landingpages"
        ],
        "summary": "Landingpage-Vorlage löschen",
        "description": "Löscht die Vorlage wie „Löschen“ unter Assets, Landingpages: Sie verschwindet aus der Liste und aus der Auswahl in Kampagnen und ist in dealsky nicht wiederherstellbar. Bereits erzeugte persönliche Seiten bleiben unverändert online (`landing_pages_count` in der Antwort), Bilder und Videos bleiben erhalten.\n\n**Schutz laufender Arbeit:** Anders als die App löscht die API keine Vorlage, die noch genutzt wird, und antwortet dann 409 mit `details.reason = template_in_use` und `details.used_by`. Genutzt heißt: eine Kampagne im Status draft, active oder paused mit dieser Vorlage, eine nicht abgeschlossene Briefkampagne, ein laufender Landingpage-Lauf für eine Liste oder eine laufende Postfach-Sequenz bzw. wartende Video-Nachricht mit dieser Vorlage. `error.details.used_by` nennt je Fund `type` (campaign, letter_campaign, landing_page_job, inbox_sequence, inbox_video_send), `id`, `name` (Kampagnenname, sonst null), `status` und je nach Art `campaign_id`, `list_id` oder `lead_id`. Der Test-Key prüft dasselbe.\n\nDie Antwort hat das Format von `GET /v1/landing-page-templates/{id}` mit `status: deleted`; ein späterer Abruf antwortet 404. Gelöschte oder fremde Vorlagen antworten 404.\n\n**Berechtigung:** `write:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Vorlage",
              "format": "uuid"
            },
            "description": "ID der Vorlage"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "name": "Outreach Geschäftsführer",
                          "description": null,
                          "status": "active",
                          "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                          "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "created_at": "2026-09-02T10:15:00.000Z",
                          "updated_at": "2026-10-14T16:40:00.000Z",
                          "structure": {
                            "layout": "variant1",
                            "sections": [
                              "comparison",
                              "cta",
                              "approach",
                              "finalCta"
                            ],
                            "hidden_sections": [
                              "faq"
                            ],
                            "blocks": [
                              {
                                "type": "text",
                                "count": 2
                              },
                              {
                                "type": "testimonial",
                                "count": 1
                              }
                            ],
                            "booking_page_blocks": [
                              "heading",
                              "calendar_embed"
                            ],
                            "thank_you_page_blocks": [
                              "heading",
                              "text"
                            ],
                            "hero_video_type": "personalized",
                            "external_cta_url": null,
                            "seo_title": "Ein Video für {{first_name}}",
                            "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                          },
                          "landing_pages_count": 42
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Vorlage (template_id bei den persönlichen Seiten)",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Vorlage wie in der App"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Beschreibung der Vorlage, null wenn keine hinterlegt ist"
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "active = in Kampagnen und im Impact Studio wählbar"
                        },
                        "thumbnail_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorschaubild der Vorlage"
                        },
                        "preview_url": {
                          "type": "string",
                          "description": "Vorschau mit Beispiel-Lead in dealsky (braucht eine Anmeldung in dealsky). Vorlagen selbst haben keine öffentliche Adresse."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Anlagezeitpunkt der Vorlage (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte Änderung der Vorlage (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "structure": {
                          "type": "object",
                          "description": "Aufbau der Vorlage ohne Editor-Daten (Texte, Farben, Stile): Abschnitte, Blöcke, Video-Art, SEO-Angaben",
                          "properties": {
                            "layout": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Grundaufbau: variant1 oder variant2"
                            },
                            "sections": {
                              "type": [
                                "array",
                                "null"
                              ],
                              "description": "Sichtbare Abschnitte unter dem Kopfbereich mit Video in ihrer Reihenfolge, z. B. comparison, cta, approach, faq, finalCta. null = Standardreihenfolge der Vorlage",
                              "items": {
                                "type": "string"
                              }
                            },
                            "hidden_sections": {
                              "type": "array",
                              "description": "Ausgeblendete Abschnitte",
                              "items": {
                                "type": "string"
                              }
                            },
                            "blocks": {
                              "type": "array",
                              "description": "Zusätzliche Blöcke auf der Hauptseite je Typ",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "description": "Blocktyp, z. B. text, image, explainer_video, video_personalized, calendar_embed, testimonial"
                                  },
                                  "count": {
                                    "type": "integer",
                                    "description": "Anzahl Blöcke dieses Typs"
                                  }
                                },
                                "additionalProperties": false
                              }
                            },
                            "booking_page_blocks": {
                              "type": "array",
                              "description": "Blocktypen der Buchungsseite. Leer, wenn ein externer CTA-Link aktiv ist.",
                              "items": {
                                "type": "string"
                              }
                            },
                            "thank_you_page_blocks": {
                              "type": "array",
                              "description": "Blocktypen der Danke-Seite. Leer, wenn ein externer CTA-Link aktiv ist.",
                              "items": {
                                "type": "string"
                              }
                            },
                            "hero_video_type": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "personalized = je Lead ein eigenes Video, static = dasselbe Video für alle"
                            },
                            "external_cta_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ziel der Buttons, wenn sie auf eine externe Seite statt auf die Buchungsseite führen"
                            },
                            "seo_title": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Titel für Suchmaschinen und Link-Vorschau, Platzhalter wie {{first_name}} werden je Lead ersetzt"
                            },
                            "seo_description": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Beschreibung für Suchmaschinen und Link-Vorschau, null wenn keine hinterlegt ist"
                            }
                          },
                          "additionalProperties": false
                        },
                        "landing_pages_count": {
                          "type": "integer",
                          "description": "Persönliche Landingpages, die aus dieser Vorlage erzeugt wurden"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "name": "Outreach Geschäftsführer",
                        "description": null,
                        "status": "deleted",
                        "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                        "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "created_at": "2026-09-02T10:15:00.000Z",
                        "updated_at": "2026-10-18T09:50:00.000Z",
                        "structure": {
                          "layout": "variant1",
                          "sections": [
                            "comparison",
                            "cta",
                            "approach",
                            "finalCta"
                          ],
                          "hidden_sections": [
                            "faq"
                          ],
                          "blocks": [
                            {
                              "type": "text",
                              "count": 2
                            },
                            {
                              "type": "testimonial",
                              "count": 1
                            }
                          ],
                          "booking_page_blocks": [
                            "heading",
                            "calendar_embed"
                          ],
                          "thank_you_page_blocks": [
                            "heading",
                            "text"
                          ],
                          "hero_video_type": "personalized",
                          "external_cta_url": null,
                          "seo_title": "Ein Video für {{first_name}}",
                          "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                        },
                        "landing_pages_count": 42
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/landing-pages": {
      "get": {
        "operationId": "listLandingPages",
        "tags": [
          "Landingpages"
        ],
        "summary": "Persönliche Landingpages auflisten",
        "description": "Die persönlichen Seiten je Lead, wie im Impact Studio unter Inhalte, neueste zuerst, jeweils mit öffentlichem Link. Kennzahlen stehen beim Abruf einer einzelnen Seite. Für alle Seiten einer Liste oder Kampagne eignet sich `GET /v1/leads?list_id=…` bzw. `?campaign_id=…`: jeder Lead trägt seinen Link in `landing_page_url`.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "lead_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Seiten dieses Leads (ein Lead kann mehrere haben, wenn neu erzeugt wurde)",
              "format": "uuid"
            },
            "description": "Nur Seiten dieses Leads (ein Lead kann mehrere haben, wenn neu erzeugt wurde)"
          },
          {
            "name": "template_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Seiten aus dieser Vorlage",
              "format": "uuid"
            },
            "description": "Nur Seiten aus dieser Vorlage"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Seiten mit diesem Status, z. B. active",
              "maxLength": 50
            },
            "description": "Nur Seiten mit diesem Status, z. B. active"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Seiten, die seitdem erzeugt wurden (für Abgleiche)",
              "format": "date-time"
            },
            "description": "Nur Seiten, die seitdem erzeugt wurden (für Abgleiche)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "3e8f1a2b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                            "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                            "template_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                            "slug": "max-mustermann",
                            "url": "https://beispiel.dealsky.app/max-mustermann",
                            "lead_name": "Max Mustermann",
                            "company_name": "Beispiel GmbH",
                            "status": "active",
                            "expires_at": null,
                            "video_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.mp4",
                            "video_poster_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.jpg",
                            "created_at": "2026-10-14T09:00:00.000Z",
                            "updated_at": "2026-10-14T09:00:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der persönlichen Landingpage",
                            "format": "uuid"
                          },
                          "lead_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Lead, dem die Seite gehört, null bei Seiten ohne Lead",
                            "format": "uuid"
                          },
                          "template_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vorlage, aus der die Seite erzeugt wurde",
                            "format": "uuid"
                          },
                          "slug": {
                            "type": "string",
                            "description": "Letzter Teil der Adresse. Format nach Einstellung unter Rechtliches (anonym, Vorname, Vor- und Nachname, Firma)"
                          },
                          "url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Öffentliche Adresse: eigene Domain, wenn eine aktiv ist, sonst {workspace}.dealsky.app. null, wenn keine Domain eingerichtet ist"
                          },
                          "lead_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Name des Leads, wie er beim Erzeugen auf die Seite geschrieben wurde"
                          },
                          "company_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Firma des Leads, wie sie beim Erzeugen auf die Seite geschrieben wurde"
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Status der Seite, z. B. active. Gelöschte Seiten liefert die API nicht"
                          },
                          "expires_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Danach wird die Seite automatisch gelöscht. null = ohne Ablauf",
                            "format": "date-time"
                          },
                          "video_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Video oben auf der Seite (bei personalisierten Vorlagen das Video des Leads)"
                          },
                          "video_poster_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vorschaubild zum Video oben auf der Seite, null ohne Vorschaubild"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Erzeugt am (ISO 8601, UTC); ab hier zählen die Kennzahlen",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzte Änderung der Seite (ISO 8601, UTC)",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "3e8f1a2b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "template_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "slug": "max-mustermann",
                          "url": "https://beispiel.dealsky.app/max-mustermann",
                          "lead_name": "Max Mustermann",
                          "company_name": "Beispiel GmbH",
                          "status": "active",
                          "expires_at": null,
                          "video_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.mp4",
                          "video_poster_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.jpg",
                          "created_at": "2026-10-14T09:00:00.000Z",
                          "updated_at": "2026-10-14T09:00:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/landing-pages/{id}": {
      "get": {
        "operationId": "getLandingPage",
        "tags": [
          "Landingpages"
        ],
        "summary": "Eine persönliche Landingpage abrufen",
        "description": "Mit öffentlichem Link, Domain und Kennzahlen (Aufrufe, Video, Klicks, Buchungen). Gezählt wird ab dem Erzeugen dieser Seite.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der persönlichen Landingpage",
              "format": "uuid"
            },
            "description": "ID der persönlichen Landingpage"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "3e8f1a2b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "template_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "slug": "max-mustermann",
                          "url": "https://beispiel.dealsky.app/max-mustermann",
                          "lead_name": "Max Mustermann",
                          "company_name": "Beispiel GmbH",
                          "status": "active",
                          "expires_at": null,
                          "video_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.mp4",
                          "video_poster_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.jpg",
                          "created_at": "2026-10-14T09:00:00.000Z",
                          "updated_at": "2026-10-14T09:00:00.000Z",
                          "domain": "beispiel.dealsky.app",
                          "domain_source": "workspace_subdomain",
                          "stats": {
                            "visits": 4,
                            "unique_visitors": 1,
                            "video_views": 2,
                            "cta_clicks": 1,
                            "booking_page_opens": 1,
                            "bookings": 1,
                            "first_visit_at": "2026-10-15T08:31:12.000Z",
                            "last_visit_at": "2026-10-17T19:04:55.000Z"
                          }
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der persönlichen Landingpage",
                          "format": "uuid"
                        },
                        "lead_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Lead, dem die Seite gehört, null bei Seiten ohne Lead",
                          "format": "uuid"
                        },
                        "template_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorlage, aus der die Seite erzeugt wurde",
                          "format": "uuid"
                        },
                        "slug": {
                          "type": "string",
                          "description": "Letzter Teil der Adresse. Format nach Einstellung unter Rechtliches (anonym, Vorname, Vor- und Nachname, Firma)"
                        },
                        "url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Öffentliche Adresse: eigene Domain, wenn eine aktiv ist, sonst {workspace}.dealsky.app. null, wenn keine Domain eingerichtet ist"
                        },
                        "lead_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Name des Leads, wie er beim Erzeugen auf die Seite geschrieben wurde"
                        },
                        "company_name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Firma des Leads, wie sie beim Erzeugen auf die Seite geschrieben wurde"
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Status der Seite, z. B. active. Gelöschte Seiten liefert die API nicht"
                        },
                        "expires_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Danach wird die Seite automatisch gelöscht. null = ohne Ablauf",
                          "format": "date-time"
                        },
                        "video_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Video oben auf der Seite (bei personalisierten Vorlagen das Video des Leads)"
                        },
                        "video_poster_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorschaubild zum Video oben auf der Seite, null ohne Vorschaubild"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Erzeugt am (ISO 8601, UTC); ab hier zählen die Kennzahlen",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte Änderung der Seite (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "domain": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Domain der Adresse"
                        },
                        "domain_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "custom_domain = eigene Domain, workspace_subdomain = {workspace}.dealsky.app",
                          "enum": [
                            "custom_domain",
                            "workspace_subdomain",
                            null
                          ]
                        },
                        "stats": {
                          "type": "object",
                          "description": "Kennzahlen seit dem Erzeugen der Seite. Ist das Tracking in den Einstellungen aus, wird nichts gezählt.",
                          "properties": {
                            "visits": {
                              "type": "integer",
                              "description": "Seitenaufrufe (ohne erkannte Bots und Link-Vorschauen)"
                            },
                            "unique_visitors": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Verschiedene Leads mit mindestens einem Aufruf, gezählt wie in der Kampagnen-Statistik der App. Eine persönliche Seite gehört genau einem Lead, darum 0 oder 1. dealsky speichert keine Besucherkennung, mehrere Geräte desselben Leads zählen also als ein Besucher. null bei Seiten ohne Lead."
                            },
                            "video_views": {
                              "type": "integer",
                              "description": "Video gestartet (Hauptvideo der Seite)"
                            },
                            "cta_clicks": {
                              "type": "integer",
                              "description": "Klicks auf die Buttons der Seite (Kopf, Mitte, Ende, Erklärvideo)"
                            },
                            "booking_page_opens": {
                              "type": "integer",
                              "description": "Buchungsseite geöffnet"
                            },
                            "bookings": {
                              "type": "integer",
                              "description": "Termine über die Seite gebucht"
                            },
                            "first_visit_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Erster Seitenaufruf (ISO 8601, UTC), null ohne Aufruf",
                              "format": "date-time"
                            },
                            "last_visit_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Letzter Seitenaufruf (ISO 8601, UTC), null ohne Aufruf",
                              "format": "date-time"
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "3e8f1a2b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "template_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "slug": "max-mustermann",
                        "url": "https://beispiel.dealsky.app/max-mustermann",
                        "lead_name": "Max Mustermann",
                        "company_name": "Beispiel GmbH",
                        "status": "active",
                        "expires_at": null,
                        "video_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.mp4",
                        "video_poster_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.jpg",
                        "created_at": "2026-10-14T09:00:00.000Z",
                        "updated_at": "2026-10-14T09:00:00.000Z",
                        "domain": "beispiel.dealsky.app",
                        "domain_source": "workspace_subdomain",
                        "stats": {
                          "visits": 4,
                          "unique_visitors": 1,
                          "video_views": 2,
                          "cta_clicks": 1,
                          "booking_page_opens": 1,
                          "bookings": 1,
                          "first_visit_at": "2026-10-15T08:31:12.000Z",
                          "last_visit_at": "2026-10-17T19:04:55.000Z"
                        }
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/leads/{id}/landing-page": {
      "get": {
        "operationId": "getLeadLandingPage",
        "tags": [
          "Landingpages"
        ],
        "summary": "Link der Landingpage eines Leads",
        "description": "Der aktuelle öffentliche Link der neuesten Landingpage des Leads, gebildet wie in der App (eigene Domain, wenn eine aktiv ist, sonst {workspace}.dealsky.app/{slug}), dazu QR-Code, Video und Kennzahlen. Hat der Lead keine Seite (nie erzeugt, gelöscht oder abgelaufen), antwortet die API 404 mit `error.details.reason = no_landing_page`, auch wenn in `landing_page_url` des Leads noch eine alte Adresse steht.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "landing_page_id": "3e8f1a2b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                          "url": "https://angebot.beispiel.de/max-mustermann",
                          "domain": "angebot.beispiel.de",
                          "domain_source": "custom_domain",
                          "slug": "max-mustermann",
                          "template_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "qr_code_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/qr-codes/Max-Mustermann.png",
                          "video_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.mp4",
                          "video_thumbnail_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.jpg",
                          "page_video_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.mp4",
                          "expires_at": null,
                          "created_at": "2026-10-14T09:00:00.000Z",
                          "stats": {
                            "visits": 4,
                            "unique_visitors": 1,
                            "video_views": 2,
                            "cta_clicks": 1,
                            "booking_page_opens": 1,
                            "bookings": 1,
                            "first_visit_at": "2026-10-15T08:31:12.000Z",
                            "last_visit_at": "2026-10-17T19:04:55.000Z"
                          }
                        }
                      ],
                      "properties": {
                        "lead_id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "format": "uuid"
                        },
                        "landing_page_id": {
                          "type": "string",
                          "description": "ID der neuesten persönlichen Landingpage des Leads (wie GET /v1/landing-pages/{id})",
                          "format": "uuid"
                        },
                        "url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Aktueller öffentlicher Link, gebildet wie in der App: eigene Domain, wenn eine aktiv ist, sonst {workspace}.dealsky.app/{slug}"
                        },
                        "domain": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Domain der Adresse, null wenn keine Domain eingerichtet ist"
                        },
                        "domain_source": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "custom_domain = eigene Domain, workspace_subdomain = {workspace}.dealsky.app, null ohne Domain",
                          "enum": [
                            "custom_domain",
                            "workspace_subdomain",
                            null
                          ]
                        },
                        "slug": {
                          "type": "string",
                          "description": "Letzter Teil der Adresse der Seite"
                        },
                        "template_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorlage, aus der die Seite erzeugt wurde",
                          "format": "uuid"
                        },
                        "qr_code_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "QR-Code-Bild (PNG) zur Landingpage des Leads, entsteht beim Erzeugen für Briefe"
                        },
                        "video_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Persönliches Video des Leads (Impact Studio)"
                        },
                        "video_thumbnail_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorschaubild zum persönlichen Video des Leads, null ohne Video"
                        },
                        "page_video_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Video oben auf der Seite (bei personalisierten Vorlagen dasselbe wie video_url, sonst das Video der Vorlage)"
                        },
                        "expires_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Danach wird die Seite automatisch gelöscht. null = ohne Ablauf",
                          "format": "date-time"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Erzeugt am (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "stats": {
                          "type": "object",
                          "description": "Kennzahlen seit dem Erzeugen der Seite. Ist das Tracking in den Einstellungen aus, wird nichts gezählt.",
                          "properties": {
                            "visits": {
                              "type": "integer",
                              "description": "Seitenaufrufe (ohne erkannte Bots und Link-Vorschauen)"
                            },
                            "unique_visitors": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Verschiedene Leads mit mindestens einem Aufruf, gezählt wie in der Kampagnen-Statistik der App. Eine persönliche Seite gehört genau einem Lead, darum 0 oder 1. dealsky speichert keine Besucherkennung, mehrere Geräte desselben Leads zählen also als ein Besucher. null bei Seiten ohne Lead."
                            },
                            "video_views": {
                              "type": "integer",
                              "description": "Video gestartet (Hauptvideo der Seite)"
                            },
                            "cta_clicks": {
                              "type": "integer",
                              "description": "Klicks auf die Buttons der Seite (Kopf, Mitte, Ende, Erklärvideo)"
                            },
                            "booking_page_opens": {
                              "type": "integer",
                              "description": "Buchungsseite geöffnet"
                            },
                            "bookings": {
                              "type": "integer",
                              "description": "Termine über die Seite gebucht"
                            },
                            "first_visit_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Erster Seitenaufruf (ISO 8601, UTC), null ohne Aufruf",
                              "format": "date-time"
                            },
                            "last_visit_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Letzter Seitenaufruf (ISO 8601, UTC), null ohne Aufruf",
                              "format": "date-time"
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "landing_page_id": "3e8f1a2b-5c6d-4e7f-8a9b-0c1d2e3f4a5b",
                        "url": "https://angebot.beispiel.de/max-mustermann",
                        "domain": "angebot.beispiel.de",
                        "domain_source": "custom_domain",
                        "slug": "max-mustermann",
                        "template_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                        "qr_code_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/qr-codes/Max-Mustermann.png",
                        "video_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.mp4",
                        "video_thumbnail_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.jpg",
                        "page_video_url": "https://cdn.dealskycloud.com/tenants/9d2c4b1a-0e3f-4a5b-8c7d-6e5f4a3b2c1d/videos/personalized/max-mustermann.mp4",
                        "expires_at": null,
                        "created_at": "2026-10-14T09:00:00.000Z",
                        "stats": {
                          "visits": 4,
                          "unique_visitors": 1,
                          "video_views": 2,
                          "cta_clicks": 1,
                          "booking_page_opens": 1,
                          "bookings": 1,
                          "first_visit_at": "2026-10-15T08:31:12.000Z",
                          "last_visit_at": "2026-10-17T19:04:55.000Z"
                        }
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/landing-page-templates/{id}/duplicate": {
      "post": {
        "operationId": "duplicateLandingPageTemplate",
        "tags": [
          "Landingpages"
        ],
        "summary": "Landingpage-Vorlage duplizieren",
        "description": "Legt eine Kopie einer aktiven Vorlage an, wie „Duplizieren“ unter Assets, Landingpages: dieselbe Seite (Texte, Design, Blöcke, Buchungs- und Danke-Seite, Kalender, Rechtliches), Name mit dem Zusatz (Kopie), sofort aktiv und in Kampagnen wählbar. Wie in der App ohne Vorschaubild (`thumbnail_url` ist null, bis die Kopie im Editor gespeichert wird). Persönliche Seiten der Vorlage werden nicht kopiert. Kostet nichts.\n\nDie Antwort hat das Format von `GET /v1/landing-page-templates/{id}`. Gelöschte oder fremde Vorlagen antworten 404, nicht aktive 422 mit `details.reason = template_inactive`.\n\n**Berechtigung:** `write:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID der Vorlage",
              "format": "uuid"
            },
            "description": "ID der Vorlage"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Name der Kopie. Ohne Angabe wie in der App: Name der Vorlage mit dem Zusatz (Kopie)",
                    "minLength": 1,
                    "maxLength": 200
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Kopie mit Standardnamen",
                  "value": {}
                },
                "beispiel2": {
                  "summary": "Kopie mit eigenem Namen",
                  "value": {
                    "name": "Outreach Geschäftsführer Variante B"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "name": "Outreach Geschäftsführer",
                          "description": null,
                          "status": "active",
                          "thumbnail_url": "https://imagedelivery.net/k3Xr9aQ/system/lp-template-variant1/public",
                          "preview_url": "https://app.dealsky.io/preview/demo-landing/7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "created_at": "2026-09-02T10:15:00.000Z",
                          "updated_at": "2026-10-14T16:40:00.000Z",
                          "structure": {
                            "layout": "variant1",
                            "sections": [
                              "comparison",
                              "cta",
                              "approach",
                              "finalCta"
                            ],
                            "hidden_sections": [
                              "faq"
                            ],
                            "blocks": [
                              {
                                "type": "text",
                                "count": 2
                              },
                              {
                                "type": "testimonial",
                                "count": 1
                              }
                            ],
                            "booking_page_blocks": [
                              "heading",
                              "calendar_embed"
                            ],
                            "thank_you_page_blocks": [
                              "heading",
                              "text"
                            ],
                            "hero_video_type": "personalized",
                            "external_cta_url": null,
                            "seo_title": "Ein Video für {{first_name}}",
                            "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                          },
                          "landing_pages_count": 42
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID der Vorlage (template_id bei den persönlichen Seiten)",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name der Vorlage wie in der App"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Beschreibung der Vorlage, null wenn keine hinterlegt ist"
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "active = in Kampagnen und im Impact Studio wählbar"
                        },
                        "thumbnail_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorschaubild der Vorlage"
                        },
                        "preview_url": {
                          "type": "string",
                          "description": "Vorschau mit Beispiel-Lead in dealsky (braucht eine Anmeldung in dealsky). Vorlagen selbst haben keine öffentliche Adresse."
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Anlagezeitpunkt der Vorlage (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte Änderung der Vorlage (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "structure": {
                          "type": "object",
                          "description": "Aufbau der Vorlage ohne Editor-Daten (Texte, Farben, Stile): Abschnitte, Blöcke, Video-Art, SEO-Angaben",
                          "properties": {
                            "layout": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Grundaufbau: variant1 oder variant2"
                            },
                            "sections": {
                              "type": [
                                "array",
                                "null"
                              ],
                              "description": "Sichtbare Abschnitte unter dem Kopfbereich mit Video in ihrer Reihenfolge, z. B. comparison, cta, approach, faq, finalCta. null = Standardreihenfolge der Vorlage",
                              "items": {
                                "type": "string"
                              }
                            },
                            "hidden_sections": {
                              "type": "array",
                              "description": "Ausgeblendete Abschnitte",
                              "items": {
                                "type": "string"
                              }
                            },
                            "blocks": {
                              "type": "array",
                              "description": "Zusätzliche Blöcke auf der Hauptseite je Typ",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "description": "Blocktyp, z. B. text, image, explainer_video, video_personalized, calendar_embed, testimonial"
                                  },
                                  "count": {
                                    "type": "integer",
                                    "description": "Anzahl Blöcke dieses Typs"
                                  }
                                },
                                "additionalProperties": false
                              }
                            },
                            "booking_page_blocks": {
                              "type": "array",
                              "description": "Blocktypen der Buchungsseite. Leer, wenn ein externer CTA-Link aktiv ist.",
                              "items": {
                                "type": "string"
                              }
                            },
                            "thank_you_page_blocks": {
                              "type": "array",
                              "description": "Blocktypen der Danke-Seite. Leer, wenn ein externer CTA-Link aktiv ist.",
                              "items": {
                                "type": "string"
                              }
                            },
                            "hero_video_type": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "personalized = je Lead ein eigenes Video, static = dasselbe Video für alle"
                            },
                            "external_cta_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ziel der Buttons, wenn sie auf eine externe Seite statt auf die Buchungsseite führen"
                            },
                            "seo_title": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Titel für Suchmaschinen und Link-Vorschau, Platzhalter wie {{first_name}} werden je Lead ersetzt"
                            },
                            "seo_description": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Beschreibung für Suchmaschinen und Link-Vorschau, null wenn keine hinterlegt ist"
                            }
                          },
                          "additionalProperties": false
                        },
                        "landing_pages_count": {
                          "type": "integer",
                          "description": "Persönliche Landingpages, die aus dieser Vorlage erzeugt wurden"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Kopie mit Standardnamen",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "8d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
                        "name": "Outreach Geschäftsführer (Kopie)",
                        "description": null,
                        "status": "active",
                        "thumbnail_url": null,
                        "preview_url": "https://app.dealsky.io/preview/demo-landing/8d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
                        "created_at": "2026-10-18T09:30:00.000Z",
                        "updated_at": "2026-10-18T09:30:00.000Z",
                        "structure": {
                          "layout": "variant1",
                          "sections": [
                            "comparison",
                            "cta",
                            "approach",
                            "finalCta"
                          ],
                          "hidden_sections": [
                            "faq"
                          ],
                          "blocks": [
                            {
                              "type": "text",
                              "count": 2
                            },
                            {
                              "type": "testimonial",
                              "count": 1
                            }
                          ],
                          "booking_page_blocks": [
                            "heading",
                            "calendar_embed"
                          ],
                          "thank_you_page_blocks": [
                            "heading",
                            "text"
                          ],
                          "hero_video_type": "personalized",
                          "external_cta_url": null,
                          "seo_title": "Ein Video für {{first_name}}",
                          "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                        },
                        "landing_pages_count": 0
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Kopie mit eigenem Namen",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "8d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
                        "name": "Outreach Geschäftsführer Variante B",
                        "description": null,
                        "status": "active",
                        "thumbnail_url": null,
                        "preview_url": "https://app.dealsky.io/preview/demo-landing/8d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
                        "created_at": "2026-10-18T09:30:00.000Z",
                        "updated_at": "2026-10-18T09:30:00.000Z",
                        "structure": {
                          "layout": "variant1",
                          "sections": [
                            "comparison",
                            "cta",
                            "approach",
                            "finalCta"
                          ],
                          "hidden_sections": [
                            "faq"
                          ],
                          "blocks": [
                            {
                              "type": "text",
                              "count": 2
                            },
                            {
                              "type": "testimonial",
                              "count": 1
                            }
                          ],
                          "booking_page_blocks": [
                            "heading",
                            "calendar_embed"
                          ],
                          "thank_you_page_blocks": [
                            "heading",
                            "text"
                          ],
                          "hero_video_type": "personalized",
                          "external_cta_url": null,
                          "seo_title": "Ein Video für {{first_name}}",
                          "seo_description": "Eine persönliche Nachricht von Beispiel GmbH"
                        },
                        "landing_pages_count": 0
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/leads/{id}/video": {
      "get": {
        "operationId": "getLeadVideo",
        "tags": [
          "Videos"
        ],
        "summary": "Personalisiertes Video eines Leads",
        "description": "Das aktuelle personalisierte Video des Leads mit Vorschaubild, wie es das Lead-Panel zeigt, dazu der Stand: `processing`, solange ein Video erstellt wird (auch aus dem Impact Studio oder einer Kampagne), `failed`, wenn die letzte Erstellung ohne Video gescheitert ist. `job_id` führt zum Auftrag (`GET /v1/jobs/{id}`). Kostet nichts.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Leads",
              "format": "uuid"
            },
            "description": "ID des Leads"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "status": "ready",
                          "video_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/video_1760778887103.mp4",
                          "thumbnail_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/thumbnail_1760778887103.jpg",
                          "processing_started_at": null,
                          "job_id": "3f9c2a71-5d4e-4b8a-9c1f-7e6d5a4b3c21"
                        }
                      ],
                      "properties": {
                        "lead_id": {
                          "type": "string",
                          "description": "ID des Leads",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string",
                          "description": "none: kein Video. processing: ein Video wird gerade erstellt (video_url kann noch das vorige zeigen). ready: Video vorhanden. failed: die letzte Erstellung ist gescheitert, es gibt kein Video",
                          "enum": [
                            "none",
                            "processing",
                            "ready",
                            "failed"
                          ]
                        },
                        "video_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Das personalisierte Video (MP4), wie im Lead-Panel"
                        },
                        "thumbnail_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorschaubild des Videos"
                        },
                        "processing_started_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Beginn der laufenden Erstellung, sonst null",
                          "format": "date-time"
                        },
                        "job_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Laufender, sonst neuester Video-Auftrag für diesen Lead (GET /v1/jobs/{id}). null, wenn das Video nicht über das Impact Studio, eine Kampagne oder die API entstand",
                          "format": "uuid"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Video ist fertig",
                    "value": {
                      "ok": true,
                      "data": {
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "status": "ready",
                        "video_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/video_1760778887103.mp4",
                        "thumbnail_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/thumbnail_1760778887103.jpg",
                        "processing_started_at": null,
                        "job_id": "3f9c2a71-5d4e-4b8a-9c1f-7e6d5a4b3c21"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Video wird gerade erstellt",
                    "value": {
                      "ok": true,
                      "data": {
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "status": "processing",
                        "video_url": null,
                        "thumbnail_url": null,
                        "processing_started_at": "2026-10-18T09:12:04.512Z",
                        "job_id": "3f9c2a71-5d4e-4b8a-9c1f-7e6d5a4b3c21"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/media/images": {
      "post": {
        "operationId": "uploadImage",
        "tags": [
          "Medien"
        ],
        "summary": "Bild hochladen",
        "description": "Lädt ein Bild zu Cloudflare Images hoch und legt es in der Medienbibliothek an, wie das Hochladen unter Assets, Bilder in der App. Danach steht es dort mit Name und Art (Bild, Logo, Icon) bereit, `url` ist sofort öffentlich abrufbar. Kostet keine Credits. Jeder Aufruf legt ein neues Bild an.\n\nGenau eines von `source_url` oder `data` angeben:\n\n- `source_url`: öffentliche https-Adresse der Bilddatei. Cloudflare holt die Datei selbst ab, dealsky lädt nichts herunter. Adressen mit IP statt Hostname, mit Zugangsdaten, `localhost`, `.local` und `.internal` werden abgelehnt. Typ und Größe prüft Cloudflare beim Abholen (höchstens 10 MB); ist die Datei kein Bild, zu groß oder nicht erreichbar, kommt 422 mit dem Grund. Der empfohlene Weg für alles über etwa 700 KB.\n\n- `data`: Base64 oder data-URL (`data:image/png;base64,…`). Weil der ganze Body höchstens 1 MB groß sein darf, passen so Bilder bis etwa 700 KB. Der Typ wird am Dateiinhalt erkannt (JPEG, PNG, WebP, SVG wie in der App, kein GIF); ein abweichender `content_type` wird abgelehnt. SVG mit Skripten, Event-Attributen (`onload=` …), `javascript:`-Links oder eingebetteten Inhalten wird abgelehnt.\n\n`category` wie in der App: `logos`, `icons`, `images` oder `pictures`. Profilbilder (Avatar) gehören zu einer Person und gehen nicht über die API.\n\nMit Test-Key wird alles geprüft (Felder, Adresse, Typ, Größe), aber nichts hochgeladen und nichts angelegt.\n\n**Berechtigung:** `write:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Genau eines von source_url oder data.",
                "properties": {
                  "source_url": {
                    "type": "string",
                    "description": "https-Adresse der Bilddatei; Cloudflare holt sie ab",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "data": {
                    "type": "string",
                    "description": "Bild als Base64 oder data-URL; der Body ist auf 1 MB begrenzt"
                  },
                  "category": {
                    "type": "string",
                    "description": "Bereich in der Bibliothek: logos, icons, images, pictures",
                    "enum": [
                      "logos",
                      "images",
                      "icons",
                      "pictures"
                    ]
                  },
                  "file_name": {
                    "type": "string",
                    "description": "Anzeigename; fließt bereinigt in die Bild-ID ein",
                    "maxLength": 200
                  },
                  "content_type": {
                    "type": "string",
                    "description": "Nur mit data: angegebener Typ, muss zum Inhalt passen",
                    "enum": [
                      "image/jpeg",
                      "image/png",
                      "image/webp",
                      "image/svg+xml"
                    ]
                  }
                },
                "required": [
                  "category"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Logo von einer Adresse abholen lassen",
                  "value": {
                    "source_url": "https://www.beispiel.de/assets/logo-beispiel.png",
                    "category": "logos"
                  }
                },
                "beispiel2": {
                  "summary": "Kleines Bild als data-URL",
                  "value": {
                    "data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGP4z8DwHwAFAAH/iZk9HQAAAABJRU5ErkJggg==",
                    "category": "images",
                    "file_name": "teamfoto.png"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a",
                          "url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/logos/1760781120000_9f2c1a7b_logo-beispiel.png/public",
                          "cf_image_id": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/logos/1760781120000_9f2c1a7b_logo-beispiel.png",
                          "type": "logo",
                          "category": "logos",
                          "name": "logo-beispiel.png",
                          "created_at": "2026-10-18T10:12:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID in der Medienbibliothek (tenant_assets)",
                          "format": "uuid"
                        },
                        "url": {
                          "type": "string",
                          "description": "Öffentliche Adresse des Bildes bei Cloudflare Images (Variante public), sofort abrufbar"
                        },
                        "cf_image_id": {
                          "type": "string",
                          "description": "Bild-ID bei Cloudflare Images"
                        },
                        "type": {
                          "type": "string",
                          "description": "Art in der Bibliothek: logos → logo, icons → icon, images und pictures → image",
                          "enum": [
                            "image",
                            "logo",
                            "icon"
                          ]
                        },
                        "category": {
                          "type": "string",
                          "description": "Bereich in der Bibliothek, wie beim Hochladen angegeben: logos, icons, images, pictures",
                          "enum": [
                            "logos",
                            "images",
                            "icons",
                            "pictures"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "description": "Anzeigename (file_name, sonst aus der URL, sonst asset)"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt, an dem das Bild in der Bibliothek angelegt wurde",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Logo von einer Adresse abholen lassen",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a",
                        "url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/logos/1760781120000_9f2c1a7b_logo-beispiel.png/public",
                        "cf_image_id": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/logos/1760781120000_9f2c1a7b_logo-beispiel.png",
                        "type": "logo",
                        "category": "logos",
                        "name": "logo-beispiel.png",
                        "created_at": "2026-10-18T10:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Kleines Bild als data-URL",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "4e5f6a7b-8c9d-4e0f-8a1b-2c3d4e5f6a7b",
                        "url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/images/images/1760781180000_2b7d4e1c_teamfoto.png/public",
                        "cf_image_id": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/images/images/1760781180000_2b7d4e1c_teamfoto.png",
                        "type": "image",
                        "category": "images",
                        "name": "teamfoto.png",
                        "created_at": "2026-10-18T10:12:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/media": {
      "get": {
        "operationId": "listMedia",
        "tags": [
          "Medien"
        ],
        "summary": "Medien auflisten",
        "description": "Bilder, Logos, Icons, Videos und Sprachnachrichten aus der Medienbibliothek, wie sie in der App unter Assets (Videos und Bilder, Sprachnachrichten) stehen, neueste zuerst. Gelöschte Einträge fehlen wie in der App. Landingpage-Vorlagen stehen nicht hier, sondern unter `GET /v1/landing-page-templates`. Von dealsky mitgelieferte System-Videos, die die App zusätzlich zeigt, liefert die API nicht.\n\nFilter: `kind` fasst die Typen zusammen: `image` (image, logo, icon), `video` (static_video und die älteren hauptvideo, sprachsync_video, video; dealsky behandelt sie seit September 2026 als eine Videoart), `audio` (audio, voice). `type` filtert auf einzelne Typen. Beides kommagetrennt, z. B. `kind=image,audio`. `q` sucht im Namen.\n\nSichtbarkeit wie in der App: Mit dem Recht `outreach` sieht die Person, der der Key gehört, alles. Mit nur `outreach.videos` (Mitarbeiter, die eigene Videos aufnehmen) sieht sie nur Videos und davon nur die eigenen. Fragt so ein Key ausdrücklich nach Bildern oder Audio, kommt 403 mit `details.required_permission = \"outreach\"`.\n\n`url` ist die öffentliche Adresse, mit der die App die Datei zeigt oder abspielt. Speicherpfade und interne Angaben gibt die API nicht heraus.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach.videos` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "image, video, audio; kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "image",
                  "video",
                  "audio"
                ]
              }
            },
            "description": "image, video, audio; kommagetrennt",
            "style": "form",
            "explode": false
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Einzelne Typen, kommagetrennt, z. B. logo,icon",
              "items": {
                "type": "string",
                "enum": [
                  "image",
                  "logo",
                  "icon",
                  "static_video",
                  "hauptvideo",
                  "sprachsync_video",
                  "video",
                  "audio",
                  "voice"
                ]
              }
            },
            "description": "Einzelne Typen, kommagetrennt, z. B. logo,icon",
            "style": "form",
            "explode": false
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Suche im Namen (Teilstring, Groß/Klein egal)",
              "maxLength": 200
            },
            "description": "Suche im Namen (Teilstring, Groß/Klein egal)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                            "name": "Vorstellung Geschäftsführung",
                            "type": "static_video",
                            "kind": "video",
                            "url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760258400000_vorstellung.mp4",
                            "thumbnail_url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/images/images/1760258460000_vorstellung-vorschau.jpg/public",
                            "description": "Kurzes Intro für Landingpages und LinkedIn",
                            "duration_seconds": 74,
                            "size_mb": null,
                            "is_default": false,
                            "created_at": "2026-10-12T08:41:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID in der Medienbibliothek",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Anzeigename wie in der App"
                          },
                          "type": {
                            "type": "string",
                            "description": "Typ in der Bibliothek. Neue Videos haben static_video, ältere auch hauptvideo, sprachsync_video oder video",
                            "enum": [
                              "image",
                              "logo",
                              "icon",
                              "static_video",
                              "hauptvideo",
                              "sprachsync_video",
                              "video",
                              "audio",
                              "voice"
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "description": "Art: image (Bild, Logo, Icon), video, audio (Sprachnachricht)",
                            "enum": [
                              "image",
                              "video",
                              "audio"
                            ]
                          },
                          "url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Öffentliche Adresse, mit der die App die Datei zeigt oder abspielt (Bilder bei Cloudflare Images, Videos und Audio auf cdn.dealskycloud.com)"
                          },
                          "thumbnail_url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Vorschaubild eines Videos. Bei Bildern ist url selbst das Bild"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Beschreibung (bei Videos in der App pflegbar)"
                          },
                          "duration_seconds": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Länge in Sekunden bei Videos und Sprachnachrichten, falls beim Hochladen gemessen"
                          },
                          "size_mb": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "Dateigröße in MB, falls gespeichert (bei Sprachnachrichten)"
                          },
                          "is_default": {
                            "type": "boolean",
                            "description": "In der App als Standard markiert (Stern bei Logos und Icons)"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt, an dem das Medium in der Bibliothek angelegt wurde",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Alles, neueste zuerst",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a",
                          "name": "logo-beispiel.png",
                          "type": "logo",
                          "kind": "image",
                          "url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/logos/1760781120000_9f2c1a7b_logo-beispiel.png/public",
                          "thumbnail_url": null,
                          "description": null,
                          "duration_seconds": null,
                          "size_mb": null,
                          "is_default": true,
                          "created_at": "2026-10-18T10:12:00.000Z"
                        },
                        {
                          "id": "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
                          "name": "Sprachnachricht · 14.10. 09:12",
                          "type": "audio",
                          "kind": "audio",
                          "url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760425920000_sprachnachricht.m4a",
                          "thumbnail_url": null,
                          "description": null,
                          "duration_seconds": 23,
                          "size_mb": 0.37,
                          "is_default": false,
                          "created_at": "2026-10-14T07:12:00.000Z"
                        },
                        {
                          "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                          "name": "Vorstellung Geschäftsführung",
                          "type": "static_video",
                          "kind": "video",
                          "url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760258400000_vorstellung.mp4",
                          "thumbnail_url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/images/images/1760258460000_vorstellung-vorschau.jpg/public",
                          "description": "Kurzes Intro für Landingpages und LinkedIn",
                          "duration_seconds": 74,
                          "size_mb": null,
                          "is_default": false,
                          "created_at": "2026-10-12T08:41:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Nur Logos und Icons",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "3d4e5f6a-7b8c-4d9e-8f0a-1b2c3d4e5f6a",
                          "name": "logo-beispiel.png",
                          "type": "logo",
                          "kind": "image",
                          "url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/logos/1760781120000_9f2c1a7b_logo-beispiel.png/public",
                          "thumbnail_url": null,
                          "description": null,
                          "duration_seconds": null,
                          "size_mb": null,
                          "is_default": true,
                          "created_at": "2026-10-18T10:12:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach.videos",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/media/{id}": {
      "get": {
        "operationId": "getMedia",
        "tags": [
          "Medien"
        ],
        "summary": "Ein Medium abrufen",
        "description": "Ein Eintrag der Medienbibliothek mit denselben Feldern wie in der Liste. 404, wenn es die ID im Konto nicht gibt, der Eintrag gelöscht ist oder keine Mediendatei ist (eine Landingpage-Vorlage steht unter `GET /v1/landing-page-templates/{id}`). Mit nur dem Recht `outreach.videos` ergeben fremde Videos 404 und Bilder oder Sprachnachrichten 403 mit `details.required_permission = \"outreach\"`, wie in der App.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach.videos` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Mediums",
              "format": "uuid"
            },
            "description": "ID des Mediums"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                          "name": "Vorstellung Geschäftsführung",
                          "type": "static_video",
                          "kind": "video",
                          "url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760258400000_vorstellung.mp4",
                          "thumbnail_url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/images/images/1760258460000_vorstellung-vorschau.jpg/public",
                          "description": "Kurzes Intro für Landingpages und LinkedIn",
                          "duration_seconds": 74,
                          "size_mb": null,
                          "is_default": false,
                          "created_at": "2026-10-12T08:41:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID in der Medienbibliothek",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Anzeigename wie in der App"
                        },
                        "type": {
                          "type": "string",
                          "description": "Typ in der Bibliothek. Neue Videos haben static_video, ältere auch hauptvideo, sprachsync_video oder video",
                          "enum": [
                            "image",
                            "logo",
                            "icon",
                            "static_video",
                            "hauptvideo",
                            "sprachsync_video",
                            "video",
                            "audio",
                            "voice"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "description": "Art: image (Bild, Logo, Icon), video, audio (Sprachnachricht)",
                          "enum": [
                            "image",
                            "video",
                            "audio"
                          ]
                        },
                        "url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Öffentliche Adresse, mit der die App die Datei zeigt oder abspielt (Bilder bei Cloudflare Images, Videos und Audio auf cdn.dealskycloud.com)"
                        },
                        "thumbnail_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorschaubild eines Videos. Bei Bildern ist url selbst das Bild"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Beschreibung (bei Videos in der App pflegbar)"
                        },
                        "duration_seconds": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Länge in Sekunden bei Videos und Sprachnachrichten, falls beim Hochladen gemessen"
                        },
                        "size_mb": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Dateigröße in MB, falls gespeichert (bei Sprachnachrichten)"
                        },
                        "is_default": {
                          "type": "boolean",
                          "description": "In der App als Standard markiert (Stern bei Logos und Icons)"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt, an dem das Medium in der Bibliothek angelegt wurde",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                        "name": "Vorstellung Geschäftsführung",
                        "type": "static_video",
                        "kind": "video",
                        "url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760258400000_vorstellung.mp4",
                        "thumbnail_url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/images/images/1760258460000_vorstellung-vorschau.jpg/public",
                        "description": "Kurzes Intro für Landingpages und LinkedIn",
                        "duration_seconds": 74,
                        "size_mb": null,
                        "is_default": false,
                        "created_at": "2026-10-12T08:41:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach.videos",
        "x-dealsky-risk": "read"
      },
      "delete": {
        "operationId": "deleteMedia",
        "tags": [
          "Medien"
        ],
        "summary": "Medium aus der Bibliothek entfernen",
        "description": "Entfernt ein Bild, Video oder eine Sprachnachricht aus der Medienbibliothek. Danach fehlt es in jeder Auswahl der App und in `GET /v1/media`. Die Datei selbst bleibt erhalten, darum zeigen ältere Nachrichten, Landingpages und Vorlagen weiter darauf. Kostet nichts.\n\nWird das Medium noch verwendet, bleibt es stehen und es kommt 409 mit `details.used_by` (Liste aus `type`, `id`, `name`). Geprüft wird wie in der App: Videos in laufenden oder pausierten Kampagnen (als Sprecher-Video) und aktiven Landingpages, Sprachnachrichten in laufenden Kampagnen, Bilder als Logo in Landingpages oder als Firmenlogo. Vorlagen sperren wie in der App nicht.\n\nRechte wie in der App: Bilder und Sprachnachrichten nur mit `outreach`. Mit nur `outreach.videos` lassen sich eigene Videos entfernen; fremde ergeben 404.\n\nMit Test-Key wird alles geprüft (auch die Verwendung), aber nichts entfernt.\n\n**Berechtigung:** `write:assets`\n\n**Recht in dealsky:** `outreach.videos` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Mediums",
              "format": "uuid"
            },
            "description": "ID des Mediums"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                          "kind": "video",
                          "type": "static_video",
                          "archived": true
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des entfernten Mediums",
                          "format": "uuid"
                        },
                        "kind": {
                          "type": "string",
                          "description": "Art: image (Bild, Logo, Icon), video, audio (Sprachnachricht)",
                          "enum": [
                            "image",
                            "video",
                            "audio"
                          ]
                        },
                        "type": {
                          "type": "string",
                          "description": "Typ in der Bibliothek, z. B. static_video, audio, logo"
                        },
                        "archived": {
                          "type": "boolean",
                          "description": "Immer true: das Medium ist aus der Bibliothek entfernt, die Datei selbst bleibt erhalten"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                        "kind": "video",
                        "type": "static_video",
                        "archived": true
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:assets",
        "x-dealsky-permission": "outreach.videos",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/domains": {
      "get": {
        "operationId": "listDomains",
        "tags": [
          "Einstellungen"
        ],
        "summary": "Eigene Domains auflisten",
        "description": "Die eigenen Domains für Landingpages, wie sie in der App unter Einrichtung, Domain stehen, älteste zuerst. Ist eine Domain aktiv, bauen dealsky und diese API die Links der persönlichen Landingpages darauf auf (`https://{hostname}/{slug}`), sonst auf `{workspace}.dealsky.app`.\n\n`status`: `verifying` heißt, der A-Record fehlt noch (Ziel steht in `dns_target`). `ssl_pending`: DNS stimmt, das Zertifikat wird eingerichtet. `active`: in Betrieb. `error`: Einrichtung gescheitert, Grund in `error_message`.\n\nAnlegen, prüfen und entfernen geht nur in der App.\n\n**Berechtigung:** `read:account`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "8c9d0e1f-2a3b-4c4d-8e5f-6a7b8c9d0e1f",
                            "hostname": "angebot.beispiel.de",
                            "status": "active",
                            "ssl_active": true,
                            "dns_target": "203.0.113.24",
                            "error_message": null,
                            "activated_at": "2026-09-03T11:20:00.000Z",
                            "created_at": "2026-09-03T10:05:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID der eigenen Domain",
                            "format": "uuid"
                          },
                          "hostname": {
                            "type": "string",
                            "description": "Domain, z. B. angebot.beispiel.de"
                          },
                          "status": {
                            "type": "string",
                            "description": "verifying: der A-Record fehlt noch. ssl_pending: DNS stimmt, das Zertifikat wird eingerichtet. active: in Betrieb. error: Einrichtung gescheitert, Grund in error_message. Weitere Werte sind möglich"
                          },
                          "ssl_active": {
                            "type": "boolean",
                            "description": "HTTPS-Zertifikat eingerichtet"
                          },
                          "dns_target": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "IP-Adresse, auf die der A-Record der Domain zeigen muss"
                          },
                          "error_message": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Grund bei status error, sonst null"
                          },
                          "activated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Wann die Domain zuletzt als aktiv gemeldet wurde (DNS geprüft, SSL eingerichtet). null, solange sie nie aktiv war",
                            "format": "date-time"
                          },
                          "created_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt, an dem die Domain in dealsky angelegt wurde",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "8c9d0e1f-2a3b-4c4d-8e5f-6a7b8c9d0e1f",
                          "hostname": "angebot.beispiel.de",
                          "status": "active",
                          "ssl_active": true,
                          "dns_target": "203.0.113.24",
                          "error_message": null,
                          "activated_at": "2026-09-03T11:20:00.000Z",
                          "created_at": "2026-09-03T10:05:00.000Z"
                        },
                        {
                          "id": "9d0e1f2a-3b4c-4d5e-9f6a-7b8c9d0e1f2a",
                          "hostname": "termin.beispiel.de",
                          "status": "verifying",
                          "ssl_active": false,
                          "dns_target": "203.0.113.24",
                          "error_message": null,
                          "activated_at": null,
                          "created_at": "2026-10-17T15:42:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:account",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/media/uploads": {
      "post": {
        "operationId": "createMediaUpload",
        "tags": [
          "Medien"
        ],
        "summary": "Video oder Audio hochladen (Adresse holen)",
        "description": "Erster Schritt für Videos und Sprachnachrichten. Liefert eine vorsignierte Adresse, an die die Datei direkt per HTTP PUT geht (nicht über die API, deren Body auf 1 MB begrenzt ist), wie das Hochladen in der App. Danach `r2_path` an `POST /v1/media/videos` bzw. `POST /v1/media/audio` übergeben. Kostet keine Credits. Erst der zweite Schritt legt etwas in der Bibliothek an.\n\nSo geht es weiter: `PUT {upload_url}` mit genau den Headern aus `upload_headers` und der Datei als Body, innerhalb von 24 Stunden (`expires_at`). Antwortet der Speicher mit 200, liegt die Datei bereit.\n\nErlaubt wie in der App: Video als `.mp4` (video/mp4), `.mov` (video/quicktime) oder `.webm` (video/webm) bis 1 GB; jedes Video wird danach in MP4 gewandelt. Audio als `.m4a` oder `.mp4` (audio/mp4) bis 20 MB, das Format, das LinkedIn für Sprachnachrichten verlangt. Andere Audio-Formate (MP3, WAV, OGG) wandelt die App beim Hochladen um und wartet darauf; über die API bitte vorher in M4A umwandeln. `content_type` muss zur Endung von `file_name` passen, `size_bytes` ist die Größe der Datei.\n\nRechte wie in der App: Videos mit `outreach.videos` (Medienseite), Sprachnachrichten nur mit `outreach` (Seite Sprachnachrichten). Ohne `outreach` kommt bei `kind=audio` 403 mit `details.required_permission = \"outreach\"`.\n\nMit Test-Key wird alles geprüft, aber keine Adresse ausgestellt (`would_presign`).\n\n**Berechtigung:** `write:assets`\n\n**Recht in dealsky:** `outreach.videos` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "kind": {
                    "type": "string",
                    "description": "video oder audio (Sprachnachricht)",
                    "enum": [
                      "video",
                      "audio"
                    ]
                  },
                  "file_name": {
                    "type": "string",
                    "description": "Dateiname mit Endung; fließt bereinigt in den Speicherort ein",
                    "maxLength": 200
                  },
                  "content_type": {
                    "type": "string",
                    "description": "Typ der Datei, passend zur Endung",
                    "enum": [
                      "video/mp4",
                      "video/quicktime",
                      "video/webm",
                      "audio/mp4"
                    ]
                  },
                  "size_bytes": {
                    "type": "integer",
                    "description": "Größe der Datei in Byte",
                    "minimum": 1,
                    "maximum": 1073741824
                  }
                },
                "required": [
                  "kind",
                  "file_name",
                  "content_type",
                  "size_bytes"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Video hochladen",
                  "value": {
                    "kind": "video",
                    "file_name": "vorstellung.mp4",
                    "content_type": "video/mp4",
                    "size_bytes": 48234112
                  }
                },
                "beispiel2": {
                  "summary": "Sprachnachricht hochladen",
                  "value": {
                    "kind": "audio",
                    "file_name": "begruessung.m4a",
                    "content_type": "audio/mp4",
                    "size_bytes": 389120
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "kind": "video",
                          "r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
                          "upload_url": "https://4f2a9c1e7b3d5a8f0e6c2b4d9a7f1e3c.r2.cloudflarestorage.com/dealskyvideos/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4?X-Amz-Date=20261018T101200Z&X-Amz-Expires=86400&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=2c9e4f1a7b3d5e8c%2F20261018%2Fauto%2Fs3%2Faws4_request&X-Amz-SignedHeaders=content-type%3Bhost&X-Amz-Signature=5d0f3c2a9e8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f",
                          "upload_method": "PUT",
                          "upload_headers": {
                            "Content-Type": "video/mp4"
                          },
                          "public_url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
                          "expires_at": "2026-10-19T10:12:00.000Z",
                          "max_size_bytes": 1073741824,
                          "next_step": "POST /v1/media/videos"
                        }
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "description": "Art des Uploads wie angefragt: video oder audio (Sprachnachricht)",
                          "enum": [
                            "video",
                            "audio"
                          ]
                        },
                        "r2_path": {
                          "type": "string",
                          "description": "Speicherort der Datei. Nach dem Hochladen unverändert an POST /v1/media/videos bzw. POST /v1/media/audio übergeben"
                        },
                        "upload_url": {
                          "type": "string",
                          "description": "Vorsignierte Adresse: die Datei per HTTP PUT als Body dorthin schicken. Nicht weitergeben, sie erlaubt das Schreiben dieser einen Datei"
                        },
                        "upload_method": {
                          "type": "string",
                          "description": "HTTP-Methode für das Hochladen an upload_url, immer PUT",
                          "enum": [
                            "PUT"
                          ]
                        },
                        "upload_headers": {
                          "type": "object",
                          "description": "Header, die der PUT genau so tragen muss (Content-Type ist Teil der Signatur)",
                          "additionalProperties": true
                        },
                        "public_url": {
                          "type": "string",
                          "description": "Öffentliche Adresse der Rohdatei nach dem Hochladen"
                        },
                        "expires_at": {
                          "type": "string",
                          "description": "Bis dahin gilt upload_url (24 Stunden, wie in der App)",
                          "format": "date-time"
                        },
                        "max_size_bytes": {
                          "type": "integer",
                          "description": "Höchstgröße der Datei für diese Art"
                        },
                        "next_step": {
                          "type": "string",
                          "description": "Der Aufruf nach dem Hochladen"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Video hochladen",
                    "value": {
                      "ok": true,
                      "data": {
                        "kind": "video",
                        "r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
                        "upload_url": "https://4f2a9c1e7b3d5a8f0e6c2b4d9a7f1e3c.r2.cloudflarestorage.com/dealskyvideos/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4?X-Amz-Date=20261018T101200Z&X-Amz-Expires=86400&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=2c9e4f1a7b3d5e8c%2F20261018%2Fauto%2Fs3%2Faws4_request&X-Amz-SignedHeaders=content-type%3Bhost&X-Amz-Signature=5d0f3c2a9e8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f",
                        "upload_method": "PUT",
                        "upload_headers": {
                          "Content-Type": "video/mp4"
                        },
                        "public_url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
                        "expires_at": "2026-10-19T10:12:00.000Z",
                        "max_size_bytes": 1073741824,
                        "next_step": "POST /v1/media/videos"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Sprachnachricht hochladen",
                    "value": {
                      "ok": true,
                      "data": {
                        "kind": "audio",
                        "r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760781240000_8b2e7d40_begruessung.m4a",
                        "upload_url": "https://4f2a9c1e7b3d5a8f0e6c2b4d9a7f1e3c.r2.cloudflarestorage.com/dealskyvideos/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760781240000_8b2e7d40_begruessung.m4a?X-Amz-Date=20261018T101200Z&X-Amz-Expires=86400&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=2c9e4f1a7b3d5e8c%2F20261018%2Fauto%2Fs3%2Faws4_request&X-Amz-SignedHeaders=content-type%3Bhost&X-Amz-Signature=5d0f3c2a9e8b7a6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f",
                        "upload_method": "PUT",
                        "upload_headers": {
                          "Content-Type": "audio/mp4"
                        },
                        "public_url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760781240000_8b2e7d40_begruessung.m4a",
                        "expires_at": "2026-10-19T10:12:00.000Z",
                        "max_size_bytes": 20971520,
                        "next_step": "POST /v1/media/audio"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:assets",
        "x-dealsky-permission": "outreach.videos",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/media/videos": {
      "post": {
        "operationId": "createMediaVideo",
        "tags": [
          "Medien"
        ],
        "summary": "Hochgeladenes Video in MP4 wandeln und anlegen",
        "description": "Zweiter Schritt nach `POST /v1/media/uploads` mit `kind=video` und dem PUT der Datei. Startet die Umwandlung in MP4 auf dem Server, wie die App es nach jeder Aufnahme tut (Videos müssen MP4 mit Längenangabe sein, sonst scheitern spätere Video-Nachrichten). Ist sie fertig, steht das Video in der Bibliothek (`static_video`, wie ein Upload in der App) und es gibt eine Benachrichtigung in der Glocke. Kostet keine Credits.\n\nAntwort 202 mit `job_id`. Den Stand liefert `GET /v1/jobs/{id}` (kind `video_conversion`, braucht das Recht `outreach`); bei `succeeded` steht die ID des neuen Videos in `result.asset_id`. Mit nur dem Recht `outreach.videos` erscheint das fertige Video in `GET /v1/media?kind=video`. Die Umwandlung dauert meist unter einer Minute, bei großen Dateien länger.\n\nDie Datei wird beim Start nicht geprüft. Fehlt sie (PUT nicht erfolgt oder abgelaufen), endet der Auftrag mit `failed`. Ist sie kein lesbares Video, endet die Umwandlung mit einem Fehler; wie bei Aufnahmen in der App legt dealsky die Rohdatei dann nach etwa 15 Minuten ungewandelt als Video an. Das Video wird auf höchstens 720p verkleinert. Ein Vorschaubild setzt die API nicht, das geht in der App.\n\n`r2_path` muss aus einem eigenen Upload stammen, sonst 400. Für dieselbe Datei startet nur ein Auftrag: läuft er noch oder ist er fertig, kommt 409 mit `details.job_id`; nach `failed` ist ein neuer Versuch möglich.\n\nMit Test-Key wird alles geprüft, aber nichts gestartet.\n\n**Berechtigung:** `write:assets`\n\n**Recht in dealsky:** `outreach.videos` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "r2_path": {
                    "type": "string",
                    "description": "r2_path aus POST /v1/media/uploads",
                    "minLength": 10,
                    "maxLength": 300
                  },
                  "name": {
                    "type": "string",
                    "description": "Anzeigename in der Bibliothek",
                    "maxLength": 200
                  }
                },
                "required": [
                  "r2_path",
                  "name"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4",
                    "name": "Vorstellung Geschäftsführung"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "job_id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                          "kind": "video_conversion",
                          "status": "running",
                          "name": "Vorstellung Geschäftsführung",
                          "r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4"
                        }
                      ],
                      "properties": {
                        "job_id": {
                          "type": "string",
                          "description": "Auftrag der Umwandlung, abrufbar über GET /v1/jobs/{id} (kind video_conversion)",
                          "format": "uuid"
                        },
                        "kind": {
                          "type": "string",
                          "description": "Art des Auftrags, immer video_conversion",
                          "enum": [
                            "video_conversion"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "description": "Stand beim Start, immer running. Den weiteren Stand zeigt GET /v1/jobs/{id}",
                          "enum": [
                            "running"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "description": "Anzeigename, den das Video in der Bibliothek bekommt"
                        },
                        "r2_path": {
                          "type": "string",
                          "description": "Speicherort der hochgeladenen Rohdatei, wie übergeben"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "job_id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                        "kind": "video_conversion",
                        "status": "running",
                        "name": "Vorstellung Geschäftsführung",
                        "r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760781120000_3f9a2c1d_vorstellung.mp4"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:assets",
        "x-dealsky-permission": "outreach.videos",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/media/audio": {
      "post": {
        "operationId": "createMediaAudio",
        "tags": [
          "Medien"
        ],
        "summary": "Hochgeladene Sprachnachricht anlegen",
        "description": "Zweiter Schritt nach `POST /v1/media/uploads` mit `kind=audio` und dem PUT der Datei. Legt die Sprachnachricht in der Bibliothek an, wie das Hochladen unter Assets, Sprachnachrichten in der App. Sie ist sofort in Kampagnen und im Postfach auswählbar. Kostet keine Credits.\n\n`r2_path` muss aus einem eigenen Audio-Upload stammen (`.m4a` oder `.mp4`), sonst 400. Ob die Datei wirklich hochgeladen wurde, prüft die API nicht; bitte erst nach erfolgreichem PUT aufrufen. Dieselbe Datei lässt sich nur einmal anlegen (409 mit `details.id`).\n\n`duration_seconds` (Länge, wie die App sie bei Aufnahmen speichert) und `size_bytes` (füllt `size_mb`) sind freiwillig. Recht wie die Seite Sprachnachrichten: `outreach`.\n\nMit Test-Key wird alles geprüft, aber nichts angelegt.\n\n**Berechtigung:** `write:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "r2_path": {
                    "type": "string",
                    "description": "r2_path aus POST /v1/media/uploads",
                    "minLength": 10,
                    "maxLength": 300
                  },
                  "name": {
                    "type": "string",
                    "description": "Anzeigename in der Bibliothek",
                    "maxLength": 200
                  },
                  "duration_seconds": {
                    "type": "number",
                    "description": "Länge in Sekunden",
                    "minimum": 0,
                    "maximum": 3600
                  },
                  "size_bytes": {
                    "type": "integer",
                    "description": "Größe der Datei in Byte, wie beim Hochladen angegeben",
                    "minimum": 1,
                    "maximum": 20971520
                  }
                },
                "required": [
                  "r2_path",
                  "name"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "r2_path": "tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760781240000_8b2e7d40_begruessung.m4a",
                    "name": "Begrüßung Herbst",
                    "duration_seconds": 23,
                    "size_bytes": 389120
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "6a7b8c9d-0e1f-4a2b-8c3d-4e5f6a7b8c9d",
                          "name": "Vorstellung Geschäftsführung",
                          "type": "static_video",
                          "kind": "video",
                          "url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/videos/static/1760258400000_vorstellung.mp4",
                          "thumbnail_url": "https://imagedelivery.net/Xk3bQ9cR7tLm2pWv8yZa1g/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/images/images/1760258460000_vorstellung-vorschau.jpg/public",
                          "description": "Kurzes Intro für Landingpages und LinkedIn",
                          "duration_seconds": 74,
                          "size_mb": null,
                          "is_default": false,
                          "created_at": "2026-10-12T08:41:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID in der Medienbibliothek",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Anzeigename wie in der App"
                        },
                        "type": {
                          "type": "string",
                          "description": "Typ in der Bibliothek. Neue Videos haben static_video, ältere auch hauptvideo, sprachsync_video oder video",
                          "enum": [
                            "image",
                            "logo",
                            "icon",
                            "static_video",
                            "hauptvideo",
                            "sprachsync_video",
                            "video",
                            "audio",
                            "voice"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "description": "Art: image (Bild, Logo, Icon), video, audio (Sprachnachricht)",
                          "enum": [
                            "image",
                            "video",
                            "audio"
                          ]
                        },
                        "url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Öffentliche Adresse, mit der die App die Datei zeigt oder abspielt (Bilder bei Cloudflare Images, Videos und Audio auf cdn.dealskycloud.com)"
                        },
                        "thumbnail_url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Vorschaubild eines Videos. Bei Bildern ist url selbst das Bild"
                        },
                        "description": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Beschreibung (bei Videos in der App pflegbar)"
                        },
                        "duration_seconds": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Länge in Sekunden bei Videos und Sprachnachrichten, falls beim Hochladen gemessen"
                        },
                        "size_mb": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "Dateigröße in MB, falls gespeichert (bei Sprachnachrichten)"
                        },
                        "is_default": {
                          "type": "boolean",
                          "description": "In der App als Standard markiert (Stern bei Logos und Icons)"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt, an dem das Medium in der Bibliothek angelegt wurde",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "7b8c9d0e-1f2a-4b3c-9d4e-5f6a7b8c9d0e",
                        "name": "Begrüßung Herbst",
                        "type": "audio",
                        "kind": "audio",
                        "url": "https://cdn.dealskycloud.com/tenants/7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f/documents/audio/1760781240000_8b2e7d40_begruessung.m4a",
                        "thumbnail_url": null,
                        "description": null,
                        "duration_seconds": 23,
                        "size_mb": 0.37,
                        "is_default": false,
                        "created_at": "2026-10-18T10:14:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/jobs": {
      "get": {
        "operationId": "listJobs",
        "tags": [
          "Jobs"
        ],
        "summary": "Hintergrund-Aufträge auflisten",
        "description": "Alle Aufträge des Kontos, neueste zuerst, über alle Arten gemischt. Mehrere Filter werden mit UND verknüpft. `lead_id` findet die Video-Aufträge, die diesen Lead verarbeiten (auch Aufträge für eine ganze Liste, höchstens die 100 neuesten); Landingpages und Löschungen laufen je Liste, dafür `list_id` nutzen. Seitenweise über meta.next_cursor: Der Cursor merkt sich Zeitpunkt und ID des letzten Eintrags, darum gibt es beim Blättern keine Doppelten und keine Lücken, auch wenn inzwischen neue Aufträge dazukommen.\n\n| kind | Auftrag | progress |\n|---|---|---|\n| `landing_page` | Persönliche Landingpages für eine Liste | erzeugte Seiten von allen, wie im Impact Studio; null bei failed und cancelled |\n| `video` | Personalisierte Videos für einen Lead oder eine Liste | fertige plus fehlgeschlagene Videos von allen, wie im Fortschrittsfenster der App |\n| `list_deletion` | Liste samt aller Leads löschen | gelöschte Leads von allen; null bei failed |\n| `video_conversion` | Aufnahme schneiden und in MP4 wandeln, Sprachaufnahmen in M4A | null solange es läuft, 100 wenn fertig (die App zeigt hier auch keinen Prozentwert) |\n| `salutation` | Anreden-Erkennung (Herr/Frau) für eine Liste oder ausgewählte Leads | geprüfte Leads von allen wie im Fortschrittsfenster der App, 100 sobald die Vorschläge bereitstehen; null bei failed und cancelled |\n\nSo bilden sich die Statuswerte der App auf die fünf der API ab:\n\n| status | `landing_page` | `video` | `list_deletion` | `video_conversion` | `salutation` |\n|---|---|---|---|---|---|\n| `queued` | `pending` | kommt nicht vor | `pending` | `queued` | `queued` |\n| `running` | `generating` | `running` | `processing` | `processing` | `processing` |\n| `succeeded` | `completed`, `completed_with_errors` | `completed`, `completed_with_errors` | `completed`, `completed_with_errors` | `done` | `review_ready`, `applying`, `completed` |\n| `failed` | `failed` | `failed` | `failed` | `error` | `failed` |\n| `cancelled` | `stopped` | kommt nicht vor | kommt nicht vor | kommt nicht vor | `cancelled` |\n\n`error` ist immer ein lesbarer Text, nie eine technische Meldung. Bei `succeeded` mit einzelnen Fehlschlägen (z. B. 3 von 120 Landingpages) steht die Zahl in `result.failed` und die Erklärung in `error`. Abfragen kostet keine Credits.\n\n`salutation`: `succeeded` heißt, die Erkennung ist fertig und die Vorschläge stehen bereit. An den Leads stehen die Anreden erst, wenn jemand sie in der App bestätigt (`result.applied` wird true). Vorschläge, die 7 Tage niemand bestätigt, verwirft dealsky; der Auftrag steht dann auf `cancelled`.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Eine oder mehrere Arten, kommagetrennt",
              "items": {
                "type": "string",
                "enum": [
                  "landing_page",
                  "video",
                  "list_deletion",
                  "video_conversion",
                  "salutation"
                ]
              }
            },
            "description": "Eine oder mehrere Arten, kommagetrennt",
            "style": "form",
            "explode": false
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Ein oder mehrere Status, kommagetrennt, z. B. queued,running für alles, was noch läuft",
              "items": {
                "type": "string",
                "enum": [
                  "queued",
                  "running",
                  "succeeded",
                  "failed",
                  "cancelled"
                ]
              }
            },
            "description": "Ein oder mehrere Status, kommagetrennt, z. B. queued,running für alles, was noch läuft",
            "style": "form",
            "explode": false
          },
          {
            "name": "lead_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Video-Aufträge, die diesen Lead verarbeiten",
              "format": "uuid"
            },
            "description": "Nur Video-Aufträge, die diesen Lead verarbeiten"
          },
          {
            "name": "list_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Aufträge zu dieser Liste",
              "format": "uuid"
            },
            "description": "Nur Aufträge zu dieser Liste"
          },
          {
            "name": "created_after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur Aufträge, die seitdem gestartet wurden",
              "format": "date-time"
            },
            "description": "Nur Aufträge, die seitdem gestartet wurden"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "3f9c2a71-5d4e-4b8a-9c1f-7e6d5a4b3c21",
                            "kind": "video",
                            "status": "succeeded",
                            "progress": 100,
                            "name": null,
                            "created_at": "2026-10-18T09:12:04.512Z",
                            "updated_at": "2026-10-18T09:14:47.103Z",
                            "finished_at": "2026-10-18T09:14:47.103Z",
                            "error": null,
                            "result": {
                              "total": 1,
                              "succeeded": 1,
                              "failed": 0,
                              "template_id": null,
                              "video_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/video_1760778887103.mp4",
                              "thumbnail_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/thumbnail_1760778887103.jpg",
                              "audio_url": null,
                              "asset_id": null,
                              "media_type": null,
                              "applied": null
                            },
                            "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                            "list_id": null
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Auftrags (bei startenden Endpunkten als job_id in der Antwort)",
                            "format": "uuid"
                          },
                          "kind": {
                            "type": "string",
                            "description": "Art des Auftrags (Tabelle oben)",
                            "enum": [
                              "landing_page",
                              "video",
                              "list_deletion",
                              "video_conversion",
                              "salutation"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "description": "queued wartet, running läuft, succeeded ist durch (einzelne Fehlschläge stehen in result.failed), failed ist gescheitert, cancelled wurde gestoppt",
                            "enum": [
                              "queued",
                              "running",
                              "succeeded",
                              "failed",
                              "cancelled"
                            ]
                          },
                          "progress": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Fortschritt in Prozent wie in der App, je Art berechnet (Tabelle oben). null, wo die App keinen Wert zeigt",
                            "minimum": 0,
                            "maximum": 100
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Anzeigename wie in der App: Vorlage (landing_page), Liste (list_deletion, salutation), Aufnahme (video_conversion)"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Anlagezeitpunkt des Auftrags (ISO 8601, UTC)",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzte Änderung am Auftrag (ISO 8601, UTC), ohne eigenen Wert der Anlagezeitpunkt. Bei video_conversion der Abschluss",
                            "format": "date-time"
                          },
                          "finished_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt des Abschlusses, null solange der Auftrag läuft",
                            "format": "date-time"
                          },
                          "error": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Lesbare Erklärung bei failed oder bei Teil-Fehlschlägen, nie eine technische Meldung"
                          },
                          "result": {
                            "type": "object",
                            "description": "Ergebnis je Art; Felder, die für die Art nicht gelten, sind null",
                            "properties": {
                              "total": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Einheiten im Auftrag: Landingpages, Videos bzw. Leads der Liste (salutation: geprüfte Leads ohne Anrede)"
                              },
                              "succeeded": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "davon fertig (list_deletion: gelöscht, salutation: Anrede erkannt, in der App „Vorschläge“)"
                              },
                              "failed": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "davon fehlgeschlagen (salutation: keine sichere Anrede, in der App „manuell prüfen“)"
                              },
                              "template_id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "landing_page: verwendete Vorlage (GET /v1/landing-page-templates/{id})",
                                "format": "uuid"
                              },
                              "video_url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "video: fertiges Video, nur bei einem Auftrag für genau einen Lead (bei Listen steht es je Lead in personalized_video_url). video_conversion: das fertige MP4"
                              },
                              "thumbnail_url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Vorschaubild zu video_url"
                              },
                              "audio_url": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "video_conversion einer Sprachaufnahme: die fertige M4A-Datei"
                              },
                              "asset_id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "video_conversion: das angelegte Medium in der Mediathek",
                                "format": "uuid"
                              },
                              "media_type": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "video_conversion: Video oder Sprachaufnahme",
                                "enum": [
                                  "video",
                                  "audio",
                                  null
                                ]
                              },
                              "applied": {
                                "type": [
                                  "boolean",
                                  "null"
                                ],
                                "description": "salutation: true, wenn die erkannten Anreden an den Leads stehen; false, solange die Vorschläge auf Bestätigung in der App warten"
                              }
                            },
                            "additionalProperties": false
                          },
                          "lead_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "video: der Lead, wenn der Auftrag genau einem Lead gilt",
                            "format": "uuid"
                          },
                          "list_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Liste des Auftrags. Bei list_deletion nach dem Löschen null",
                            "format": "uuid"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Alles, was gerade läuft",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "8d2e4f6a-1b3c-4d5e-8f7a-9b0c1d2e3f4a",
                          "kind": "landing_page",
                          "status": "running",
                          "progress": 42,
                          "name": "Outreach Geschäftsführer",
                          "created_at": "2026-10-18T10:02:11.004Z",
                          "updated_at": "2026-10-18T10:05:37.881Z",
                          "finished_at": null,
                          "error": null,
                          "result": {
                            "total": 120,
                            "succeeded": 50,
                            "failed": 1,
                            "template_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                            "video_url": null,
                            "thumbnail_url": null,
                            "audio_url": null,
                            "asset_id": null,
                            "media_type": null,
                            "applied": null
                          },
                          "lead_id": null,
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Neueste Aufträge aller Arten",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "8d2e4f6a-1b3c-4d5e-8f7a-9b0c1d2e3f4a",
                          "kind": "landing_page",
                          "status": "running",
                          "progress": 42,
                          "name": "Outreach Geschäftsführer",
                          "created_at": "2026-10-18T10:02:11.004Z",
                          "updated_at": "2026-10-18T10:05:37.881Z",
                          "finished_at": null,
                          "error": null,
                          "result": {
                            "total": 120,
                            "succeeded": 50,
                            "failed": 1,
                            "template_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                            "video_url": null,
                            "thumbnail_url": null,
                            "audio_url": null,
                            "asset_id": null,
                            "media_type": null,
                            "applied": null
                          },
                          "lead_id": null,
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f"
                        },
                        {
                          "id": "3f9c2a71-5d4e-4b8a-9c1f-7e6d5a4b3c21",
                          "kind": "video",
                          "status": "succeeded",
                          "progress": 100,
                          "name": null,
                          "created_at": "2026-10-18T09:12:04.512Z",
                          "updated_at": "2026-10-18T09:14:47.103Z",
                          "finished_at": "2026-10-18T09:14:47.103Z",
                          "error": null,
                          "result": {
                            "total": 1,
                            "succeeded": 1,
                            "failed": 0,
                            "template_id": null,
                            "video_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/video_1760778887103.mp4",
                            "thumbnail_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/thumbnail_1760778887103.jpg",
                            "audio_url": null,
                            "asset_id": null,
                            "media_type": null,
                            "applied": null
                          },
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "list_id": null
                        },
                        {
                          "id": "c4b3a291-8e7d-4c6b-9a5f-4e3d2c1b0a99",
                          "kind": "list_deletion",
                          "status": "succeeded",
                          "progress": 100,
                          "name": "Messe Köln 2026",
                          "created_at": "2026-10-17T16:20:00.215Z",
                          "updated_at": "2026-10-17T16:21:42.730Z",
                          "finished_at": "2026-10-17T16:21:42.730Z",
                          "error": null,
                          "result": {
                            "total": 312,
                            "succeeded": 312,
                            "failed": 0,
                            "template_id": null,
                            "video_url": null,
                            "thumbnail_url": null,
                            "audio_url": null,
                            "asset_id": null,
                            "media_type": null,
                            "applied": null
                          },
                          "lead_id": null,
                          "list_id": null
                        },
                        {
                          "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                          "kind": "video_conversion",
                          "status": "failed",
                          "progress": null,
                          "name": "Begrüßung Herbst",
                          "created_at": "2026-10-16T14:03:55.000Z",
                          "updated_at": "2026-10-16T14:04:20.000Z",
                          "finished_at": "2026-10-16T14:04:20.000Z",
                          "error": "Das Video konnte nicht umgewandelt werden. Bitte erneut hochladen.",
                          "result": {
                            "total": null,
                            "succeeded": null,
                            "failed": null,
                            "template_id": null,
                            "video_url": null,
                            "thumbnail_url": null,
                            "audio_url": null,
                            "asset_id": null,
                            "media_type": "video",
                            "applied": null
                          },
                          "lead_id": null,
                          "list_id": null
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel3": {
                    "summary": "Anreden-Erkennung einer Liste",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
                          "kind": "salutation",
                          "status": "succeeded",
                          "progress": 100,
                          "name": "Messe Köln 2026",
                          "created_at": "2026-10-18T07:45:10.331Z",
                          "updated_at": "2026-10-18T07:46:02.918Z",
                          "finished_at": "2026-10-18T07:46:02.918Z",
                          "error": null,
                          "result": {
                            "total": 240,
                            "succeeded": 231,
                            "failed": 9,
                            "template_id": null,
                            "video_url": null,
                            "thumbnail_url": null,
                            "audio_url": null,
                            "asset_id": null,
                            "media_type": null,
                            "applied": false
                          },
                          "lead_id": null,
                          "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel4": {
                    "summary": "Videos eines Leads",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "3f9c2a71-5d4e-4b8a-9c1f-7e6d5a4b3c21",
                          "kind": "video",
                          "status": "succeeded",
                          "progress": 100,
                          "name": null,
                          "created_at": "2026-10-18T09:12:04.512Z",
                          "updated_at": "2026-10-18T09:14:47.103Z",
                          "finished_at": "2026-10-18T09:14:47.103Z",
                          "error": null,
                          "result": {
                            "total": 1,
                            "succeeded": 1,
                            "failed": 0,
                            "template_id": null,
                            "video_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/video_1760778887103.mp4",
                            "thumbnail_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/thumbnail_1760778887103.jpg",
                            "audio_url": null,
                            "asset_id": null,
                            "media_type": null,
                            "applied": null
                          },
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "list_id": null
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "tags": [
          "Jobs"
        ],
        "summary": "Stand eines Hintergrund-Auftrags",
        "description": "Ein Auftrag, egal welcher Art: Landingpages für eine Liste, personalisierte Videos, Löschen einer Liste, Umwandeln einer Aufnahme oder Anreden-Erkennung. Die ID kommt aus `GET /v1/jobs` oder als `job_id` von dem Endpunkt, der den Auftrag startet. Zum Warten etwa alle 5 bis 10 Sekunden abfragen, bis `status` succeeded, failed oder cancelled ist; `finished_at` ist dann gesetzt.\n\n| kind | Auftrag | progress |\n|---|---|---|\n| `landing_page` | Persönliche Landingpages für eine Liste | erzeugte Seiten von allen, wie im Impact Studio; null bei failed und cancelled |\n| `video` | Personalisierte Videos für einen Lead oder eine Liste | fertige plus fehlgeschlagene Videos von allen, wie im Fortschrittsfenster der App |\n| `list_deletion` | Liste samt aller Leads löschen | gelöschte Leads von allen; null bei failed |\n| `video_conversion` | Aufnahme schneiden und in MP4 wandeln, Sprachaufnahmen in M4A | null solange es läuft, 100 wenn fertig (die App zeigt hier auch keinen Prozentwert) |\n| `salutation` | Anreden-Erkennung (Herr/Frau) für eine Liste oder ausgewählte Leads | geprüfte Leads von allen wie im Fortschrittsfenster der App, 100 sobald die Vorschläge bereitstehen; null bei failed und cancelled |\n\nSo bilden sich die Statuswerte der App auf die fünf der API ab:\n\n| status | `landing_page` | `video` | `list_deletion` | `video_conversion` | `salutation` |\n|---|---|---|---|---|---|\n| `queued` | `pending` | kommt nicht vor | `pending` | `queued` | `queued` |\n| `running` | `generating` | `running` | `processing` | `processing` | `processing` |\n| `succeeded` | `completed`, `completed_with_errors` | `completed`, `completed_with_errors` | `completed`, `completed_with_errors` | `done` | `review_ready`, `applying`, `completed` |\n| `failed` | `failed` | `failed` | `failed` | `error` | `failed` |\n| `cancelled` | `stopped` | kommt nicht vor | kommt nicht vor | kommt nicht vor | `cancelled` |\n\n`error` ist immer ein lesbarer Text, nie eine technische Meldung. Bei `succeeded` mit einzelnen Fehlschlägen (z. B. 3 von 120 Landingpages) steht die Zahl in `result.failed` und die Erklärung in `error`. Abfragen kostet keine Credits.\n\n`salutation`: `succeeded` heißt, die Erkennung ist fertig und die Vorschläge stehen bereit. An den Leads stehen die Anreden erst, wenn jemand sie in der App bestätigt (`result.applied` wird true). Vorschläge, die 7 Tage niemand bestätigt, verwirft dealsky; der Auftrag steht dann auf `cancelled`.\n\n**Berechtigung:** `read:assets`\n\n**Recht in dealsky:** `outreach` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Auftrags",
              "format": "uuid"
            },
            "description": "ID des Auftrags"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "3f9c2a71-5d4e-4b8a-9c1f-7e6d5a4b3c21",
                          "kind": "video",
                          "status": "succeeded",
                          "progress": 100,
                          "name": null,
                          "created_at": "2026-10-18T09:12:04.512Z",
                          "updated_at": "2026-10-18T09:14:47.103Z",
                          "finished_at": "2026-10-18T09:14:47.103Z",
                          "error": null,
                          "result": {
                            "total": 1,
                            "succeeded": 1,
                            "failed": 0,
                            "template_id": null,
                            "video_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/video_1760778887103.mp4",
                            "thumbnail_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/thumbnail_1760778887103.jpg",
                            "audio_url": null,
                            "asset_id": null,
                            "media_type": null,
                            "applied": null
                          },
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "list_id": null
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Auftrags (bei startenden Endpunkten als job_id in der Antwort)",
                          "format": "uuid"
                        },
                        "kind": {
                          "type": "string",
                          "description": "Art des Auftrags (Tabelle oben)",
                          "enum": [
                            "landing_page",
                            "video",
                            "list_deletion",
                            "video_conversion",
                            "salutation"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "description": "queued wartet, running läuft, succeeded ist durch (einzelne Fehlschläge stehen in result.failed), failed ist gescheitert, cancelled wurde gestoppt",
                          "enum": [
                            "queued",
                            "running",
                            "succeeded",
                            "failed",
                            "cancelled"
                          ]
                        },
                        "progress": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Fortschritt in Prozent wie in der App, je Art berechnet (Tabelle oben). null, wo die App keinen Wert zeigt",
                          "minimum": 0,
                          "maximum": 100
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Anzeigename wie in der App: Vorlage (landing_page), Liste (list_deletion, salutation), Aufnahme (video_conversion)"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Anlagezeitpunkt des Auftrags (ISO 8601, UTC)",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte Änderung am Auftrag (ISO 8601, UTC), ohne eigenen Wert der Anlagezeitpunkt. Bei video_conversion der Abschluss",
                          "format": "date-time"
                        },
                        "finished_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt des Abschlusses, null solange der Auftrag läuft",
                          "format": "date-time"
                        },
                        "error": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Lesbare Erklärung bei failed oder bei Teil-Fehlschlägen, nie eine technische Meldung"
                        },
                        "result": {
                          "type": "object",
                          "description": "Ergebnis je Art; Felder, die für die Art nicht gelten, sind null",
                          "properties": {
                            "total": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Einheiten im Auftrag: Landingpages, Videos bzw. Leads der Liste (salutation: geprüfte Leads ohne Anrede)"
                            },
                            "succeeded": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "davon fertig (list_deletion: gelöscht, salutation: Anrede erkannt, in der App „Vorschläge“)"
                            },
                            "failed": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "davon fehlgeschlagen (salutation: keine sichere Anrede, in der App „manuell prüfen“)"
                            },
                            "template_id": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "landing_page: verwendete Vorlage (GET /v1/landing-page-templates/{id})",
                              "format": "uuid"
                            },
                            "video_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "video: fertiges Video, nur bei einem Auftrag für genau einen Lead (bei Listen steht es je Lead in personalized_video_url). video_conversion: das fertige MP4"
                            },
                            "thumbnail_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Vorschaubild zu video_url"
                            },
                            "audio_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "video_conversion einer Sprachaufnahme: die fertige M4A-Datei"
                            },
                            "asset_id": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "video_conversion: das angelegte Medium in der Mediathek",
                              "format": "uuid"
                            },
                            "media_type": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "video_conversion: Video oder Sprachaufnahme",
                              "enum": [
                                "video",
                                "audio",
                                null
                              ]
                            },
                            "applied": {
                              "type": [
                                "boolean",
                                "null"
                              ],
                              "description": "salutation: true, wenn die erkannten Anreden an den Leads stehen; false, solange die Vorschläge auf Bestätigung in der App warten"
                            }
                          },
                          "additionalProperties": false
                        },
                        "lead_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "video: der Lead, wenn der Auftrag genau einem Lead gilt",
                          "format": "uuid"
                        },
                        "list_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Liste des Auftrags. Bei list_deletion nach dem Löschen null",
                          "format": "uuid"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Video für einen Lead ist fertig",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "3f9c2a71-5d4e-4b8a-9c1f-7e6d5a4b3c21",
                        "kind": "video",
                        "status": "succeeded",
                        "progress": 100,
                        "name": null,
                        "created_at": "2026-10-18T09:12:04.512Z",
                        "updated_at": "2026-10-18T09:14:47.103Z",
                        "finished_at": "2026-10-18T09:14:47.103Z",
                        "error": null,
                        "result": {
                          "total": 1,
                          "succeeded": 1,
                          "failed": 0,
                          "template_id": null,
                          "video_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/video_1760778887103.mp4",
                          "thumbnail_url": "https://cdn.dealskycloud.com/tenants/9a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d/personalized/5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10/thumbnail_1760778887103.jpg",
                          "audio_url": null,
                          "asset_id": null,
                          "media_type": null,
                          "applied": null
                        },
                        "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                        "list_id": null
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Landingpages für eine Liste laufen noch",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "8d2e4f6a-1b3c-4d5e-8f7a-9b0c1d2e3f4a",
                        "kind": "landing_page",
                        "status": "running",
                        "progress": 42,
                        "name": "Outreach Geschäftsführer",
                        "created_at": "2026-10-18T10:02:11.004Z",
                        "updated_at": "2026-10-18T10:05:37.881Z",
                        "finished_at": null,
                        "error": null,
                        "result": {
                          "total": 120,
                          "succeeded": 50,
                          "failed": 1,
                          "template_id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                          "video_url": null,
                          "thumbnail_url": null,
                          "audio_url": null,
                          "asset_id": null,
                          "media_type": null,
                          "applied": null
                        },
                        "lead_id": null,
                        "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel3": {
                    "summary": "Umwandlung einer Aufnahme fehlgeschlagen",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
                        "kind": "video_conversion",
                        "status": "failed",
                        "progress": null,
                        "name": "Begrüßung Herbst",
                        "created_at": "2026-10-16T14:03:55.000Z",
                        "updated_at": "2026-10-16T14:04:20.000Z",
                        "finished_at": "2026-10-16T14:04:20.000Z",
                        "error": "Das Video konnte nicht umgewandelt werden. Bitte erneut hochladen.",
                        "result": {
                          "total": null,
                          "succeeded": null,
                          "failed": null,
                          "template_id": null,
                          "video_url": null,
                          "thumbnail_url": null,
                          "audio_url": null,
                          "asset_id": null,
                          "media_type": "video",
                          "applied": null
                        },
                        "lead_id": null,
                        "list_id": null
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel4": {
                    "summary": "Anreden erkannt, Bestätigung in der App steht aus",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
                        "kind": "salutation",
                        "status": "succeeded",
                        "progress": 100,
                        "name": "Messe Köln 2026",
                        "created_at": "2026-10-18T07:45:10.331Z",
                        "updated_at": "2026-10-18T07:46:02.918Z",
                        "finished_at": "2026-10-18T07:46:02.918Z",
                        "error": null,
                        "result": {
                          "total": 240,
                          "succeeded": 231,
                          "failed": 9,
                          "template_id": null,
                          "video_url": null,
                          "thumbnail_url": null,
                          "audio_url": null,
                          "asset_id": null,
                          "media_type": null,
                          "applied": false
                        },
                        "lead_id": null,
                        "list_id": "1f4e2d3c-7b6a-4c5d-9e8f-0a1b2c3d4e5f"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:assets",
        "x-dealsky-permission": "outreach",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/analytics/overview": {
      "get": {
        "operationId": "getAnalyticsOverview",
        "tags": [
          "Auswertung"
        ],
        "summary": "Kennzahlen wie die Statistik-Seite",
        "description": "Die Zahlen der Seite Kampagnen, Statistiken, mit denselben Formeln: Vernetzungsanfragen und Annahmequote, ausstehende Anfragen, Nachrichten und Antwortquote (Personen mit mindestens einer Nachricht, je Kampagne einmal), wer auf Antwort wartet, der Lücken-Finder (vernetzt, nie angeschrieben, in keiner laufenden Kampagne), Termine, laufende Kampagnen, Stand der Sequenzen, Landingpage-Besuche und dieselben Werte je Kampagne.\n\nZeitraum wie in der App als Kohorte: Ein Lead zählt, wenn seine Vernetzungsanfrage (sonst seine Vernetzung) im Zeitraum liegt; Leads ohne beides (noch in der Warteschlange) zählen immer. Tage gelten nach deutscher Zeit. Termine sind ein Stand ohne Zeitraum; Landingpage-Zahlen zählen Ereignisse im Zeitraum.\n\nDie Statistik einer einzelnen Kampagne mit Funnel je Schritt steht unter GET /v1/campaigns/{id}/stats; sie rechnet Annahmen zusätzlich aus dem Verlauf und kann leicht abweichen. Sichtbar sind nur Zahlen der LinkedIn-Konten, auf die die Person hinter dem Key Zugriff hat. Bei großen Konten dauert die Antwort einige Sekunden.\n\n**Berechtigung:** `read:analytics`\n\n**Recht in dealsky:** `outreach.campaigns.view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Erster Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich",
              "format": "date"
            },
            "description": "Erster Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Letzter Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich",
              "format": "date"
            },
            "description": "Letzter Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich"
          },
          {
            "name": "account_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur dieses LinkedIn-Konto (siehe /v1/linkedin/accounts)",
              "format": "uuid"
            },
            "description": "Nur dieses LinkedIn-Konto (siehe /v1/linkedin/accounts)"
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur diese Kampagne (siehe /v1/campaigns)",
              "format": "uuid"
            },
            "description": "Nur diese Kampagne (siehe /v1/campaigns)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "period": {
                            "from": "2026-10-01",
                            "to": "2026-10-18",
                            "timezone": "Europe/Berlin"
                          },
                          "filters": {
                            "account_id": null,
                            "campaign_id": null
                          },
                          "connections": {
                            "sent": 214,
                            "accepted": 81,
                            "acceptance_rate": 38,
                            "already_connected": 12,
                            "pending": 96,
                            "oldest_pending_days": 17
                          },
                          "messages": {
                            "sent": 131,
                            "messaged_people": 93,
                            "replied_people": 17,
                            "reply_rate": 18,
                            "replies": 19
                          },
                          "waiting_for_reply": {
                            "count": 76,
                            "lead_ids": [
                              "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10"
                            ]
                          },
                          "idle_connections": {
                            "count": 4,
                            "lead_ids": [
                              "7e3d1c2b-9a8f-4e6d-8c5b-4a3f2e1d0c9b"
                            ]
                          },
                          "bookings": 6,
                          "active_campaigns": 3,
                          "sequence_status": [
                            {
                              "status": "waiting_for_connection",
                              "count": 96
                            },
                            {
                              "status": "active",
                              "count": 58
                            },
                            {
                              "status": "replied",
                              "count": 17
                            }
                          ],
                          "landing_pages": {
                            "visits": 22,
                            "video_views": 9,
                            "cta_clicks": 4,
                            "bookings": 2
                          },
                          "campaigns": [
                            {
                              "campaign_id": "9d2e1f3a-4b5c-4d6e-8f7a-1b2c3d4e5f60",
                              "name": "Geschäftsführer Logistik",
                              "status": "active",
                              "leads": 180,
                              "connections_sent": 150,
                              "connections_accepted": 61,
                              "acceptance_rate": 41,
                              "messages_sent": 102,
                              "replies": 14,
                              "reply_rate": 19
                            }
                          ],
                          "calculated_at": "2026-10-18T09:30:00.000Z"
                        }
                      ],
                      "properties": {
                        "period": {
                          "type": "object",
                          "description": "Zeitraum; ohne from und to gilt der Gesamtzeitraum",
                          "properties": {
                            "from": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Erster Tag des Zeitraums (einschließlich), null ohne from",
                              "format": "date"
                            },
                            "to": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Letzter Tag des Zeitraums (einschließlich), null ohne to",
                              "format": "date"
                            },
                            "timezone": {
                              "type": "string",
                              "description": "Zeitzone der Tagesgrenzen, immer Europe/Berlin"
                            }
                          },
                          "additionalProperties": false
                        },
                        "filters": {
                          "type": "object",
                          "description": "Filter, mit denen gerechnet wurde",
                          "properties": {
                            "account_id": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Angewendeter Kontofilter aus der Query, null ohne Filter",
                              "format": "uuid"
                            },
                            "campaign_id": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Angewendeter Kampagnenfilter aus der Query, null ohne Filter",
                              "format": "uuid"
                            }
                          },
                          "additionalProperties": false
                        },
                        "connections": {
                          "type": "object",
                          "description": "Vernetzungsanfragen im Ausschnitt",
                          "properties": {
                            "sent": {
                              "type": "integer",
                              "description": "Leads mit gesendeter Vernetzungsanfrage"
                            },
                            "accepted": {
                              "type": "integer",
                              "description": "Davon vernetzt (wie die Annahmequote der App)"
                            },
                            "acceptance_rate": {
                              "type": "integer",
                              "description": "Annahmequote in Prozent",
                              "minimum": 0,
                              "maximum": 100
                            },
                            "already_connected": {
                              "type": "integer",
                              "description": "Vernetzt ohne Anfrage aus der Kampagne (war schon Kontakt)"
                            },
                            "pending": {
                              "type": "integer",
                              "description": "Ausstehende Vernetzungsanfragen"
                            },
                            "oldest_pending_days": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Alter der ältesten ausstehenden Anfrage in Tagen"
                            }
                          },
                          "additionalProperties": false
                        },
                        "messages": {
                          "type": "object",
                          "description": "Nachrichten und Antworten im Ausschnitt",
                          "properties": {
                            "sent": {
                              "type": "integer",
                              "description": "Gesendete Nachrichten (Text, Sprache, Video, InMail), jede einzeln"
                            },
                            "messaged_people": {
                              "type": "integer",
                              "description": "Personen mit mindestens einer Nachricht, je Kampagne einmal (Nenner der Antwortquote)"
                            },
                            "replied_people": {
                              "type": "integer",
                              "description": "Davon mit Antwort"
                            },
                            "reply_rate": {
                              "type": [
                                "integer",
                                "null"
                              ],
                              "description": "Antwortquote in Prozent; null, wenn noch niemand angeschrieben wurde",
                              "minimum": 0,
                              "maximum": 100
                            },
                            "replies": {
                              "type": "integer",
                              "description": "Sequenz-Einträge mit Antwort, auch ohne Nachricht davor (Funnel-Stufe Geantwortet)"
                            }
                          },
                          "additionalProperties": false
                        },
                        "waiting_for_reply": {
                          "type": "object",
                          "description": "Angeschrieben, aber noch keine Antwort (je Person)",
                          "properties": {
                            "count": {
                              "type": "integer",
                              "description": "Anzahl der Personen (Leads) insgesamt, auch über die Stichprobe hinaus",
                              "minimum": 0
                            },
                            "lead_ids": {
                              "type": "array",
                              "description": "Bis zu 50 Lead-IDs (für GET /v1/leads/{id})",
                              "items": {
                                "type": "string",
                                "format": "uuid"
                              }
                            }
                          },
                          "additionalProperties": false
                        },
                        "idle_connections": {
                          "type": "object",
                          "description": "Lücken-Finder: vernetzt, nie angeschrieben und in keiner laufenden Kampagne oder Sequenz (je Person)",
                          "properties": {
                            "count": {
                              "type": "integer",
                              "description": "Anzahl der Personen (Leads) insgesamt, auch über die Stichprobe hinaus",
                              "minimum": 0
                            },
                            "lead_ids": {
                              "type": "array",
                              "description": "Bis zu 50 Lead-IDs (für GET /v1/leads/{id})",
                              "items": {
                                "type": "string",
                                "format": "uuid"
                              }
                            }
                          },
                          "additionalProperties": false
                        },
                        "bookings": {
                          "type": "integer",
                          "description": "Leads mit Termin (Status booked oder Termin gesetzt), Stand heute, ohne Zeitraum"
                        },
                        "active_campaigns": {
                          "type": "integer",
                          "description": "Laufende Kampagnen im Ausschnitt"
                        },
                        "sequence_status": {
                          "type": "array",
                          "description": "Stand der Leads in den Sequenzen, häufigster zuerst",
                          "items": {
                            "type": "object",
                            "properties": {
                              "status": {
                                "type": "string",
                                "description": "Status des Sequenz-Eintrags, z. B. waiting_for_connection, active, replied; unknown ohne Status"
                              },
                              "count": {
                                "type": "integer",
                                "description": "Anzahl der Sequenz-Einträge mit diesem Status"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "landing_pages": {
                          "type": "object",
                          "description": "Je Lead einmal gezählt, Ereignisse im Zeitraum",
                          "properties": {
                            "visits": {
                              "type": "integer",
                              "description": "Leads mit Seitenaufruf im Zeitraum"
                            },
                            "video_views": {
                              "type": "integer",
                              "description": "Leads, die das Video gestartet haben"
                            },
                            "cta_clicks": {
                              "type": "integer",
                              "description": "Leads mit Klick auf einen Button"
                            },
                            "bookings": {
                              "type": "integer",
                              "description": "Leads mit bestätigter Buchung über die Seite"
                            }
                          },
                          "additionalProperties": false
                        },
                        "campaigns": {
                          "type": "array",
                          "description": "Je Kampagne, meiste Anfragen zuerst",
                          "items": {
                            "type": "object",
                            "properties": {
                              "campaign_id": {
                                "type": "string",
                                "description": "ID der Kampagne (für GET /v1/campaigns/{id})",
                                "format": "uuid"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Name der Kampagne; null, wenn die Person hinter dem Key die Kampagne in der App nicht sieht"
                              },
                              "status": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Status der Kampagne, z. B. active, paused, draft; null wie bei name"
                              },
                              "leads": {
                                "type": "integer",
                                "description": "Sequenz-Einträge im Ausschnitt"
                              },
                              "connections_sent": {
                                "type": "integer",
                                "description": "Leads mit gesendeter Vernetzungsanfrage in dieser Kampagne"
                              },
                              "connections_accepted": {
                                "type": "integer",
                                "description": "Davon vernetzt"
                              },
                              "acceptance_rate": {
                                "type": "integer",
                                "description": "Annahmequote in Prozent",
                                "minimum": 0,
                                "maximum": 100
                              },
                              "messages_sent": {
                                "type": "integer",
                                "description": "Gesendete Nachrichten (Text, Sprache, Video, InMail) in dieser Kampagne"
                              },
                              "replies": {
                                "type": "integer",
                                "description": "Sequenz-Einträge mit Antwort in dieser Kampagne"
                              },
                              "reply_rate": {
                                "type": [
                                  "integer",
                                  "null"
                                ],
                                "description": "Antwortquote in Prozent, null ohne angeschriebene Person",
                                "minimum": 0,
                                "maximum": 100
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "calculated_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Berechnung (die Zahlen werden bei jedem Aufruf neu gerechnet)",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Oktober bis heute",
                    "value": {
                      "ok": true,
                      "data": {
                        "period": {
                          "from": "2026-10-01",
                          "to": "2026-10-18",
                          "timezone": "Europe/Berlin"
                        },
                        "filters": {
                          "account_id": null,
                          "campaign_id": null
                        },
                        "connections": {
                          "sent": 214,
                          "accepted": 81,
                          "acceptance_rate": 38,
                          "already_connected": 12,
                          "pending": 96,
                          "oldest_pending_days": 17
                        },
                        "messages": {
                          "sent": 131,
                          "messaged_people": 93,
                          "replied_people": 17,
                          "reply_rate": 18,
                          "replies": 19
                        },
                        "waiting_for_reply": {
                          "count": 76,
                          "lead_ids": [
                            "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10"
                          ]
                        },
                        "idle_connections": {
                          "count": 4,
                          "lead_ids": [
                            "7e3d1c2b-9a8f-4e6d-8c5b-4a3f2e1d0c9b"
                          ]
                        },
                        "bookings": 6,
                        "active_campaigns": 3,
                        "sequence_status": [
                          {
                            "status": "waiting_for_connection",
                            "count": 96
                          },
                          {
                            "status": "active",
                            "count": 58
                          },
                          {
                            "status": "replied",
                            "count": 17
                          }
                        ],
                        "landing_pages": {
                          "visits": 22,
                          "video_views": 9,
                          "cta_clicks": 4,
                          "bookings": 2
                        },
                        "campaigns": [
                          {
                            "campaign_id": "9d2e1f3a-4b5c-4d6e-8f7a-1b2c3d4e5f60",
                            "name": "Geschäftsführer Logistik",
                            "status": "active",
                            "leads": 180,
                            "connections_sent": 150,
                            "connections_accepted": 61,
                            "acceptance_rate": 41,
                            "messages_sent": 102,
                            "replies": 14,
                            "reply_rate": 19
                          }
                        ],
                        "calculated_at": "2026-10-18T09:30:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:analytics",
        "x-dealsky-permission": "outreach.campaigns.view",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/analytics/daily": {
      "get": {
        "operationId": "getAnalyticsDaily",
        "tags": [
          "Auswertung"
        ],
        "summary": "Werte je Tag",
        "description": "Je Kalendertag (deutsche Zeit): gesendete Vernetzungsanfragen, neue Kontakte, gesendete Nachrichten und eingegangene Antworten. Neue Kontakte sind die Werte der Karten Vernetzungs-Wachstum und Neue Kontakte pro Tag der App, gezählt aus den Kampagnen (Kontakte außerhalb von Kampagnen liest die App live bei LinkedIn, die gibt es hier nicht). Ohne Angabe die letzten 30 Tage bis heute, höchstens 92 Tage. Jeder Wert zählt an dem Tag, an dem es passiert ist, nicht als Kohorte. Sichtbar sind nur Zahlen der LinkedIn-Konten, auf die die Person hinter dem Key Zugriff hat.\n\n**Berechtigung:** `read:analytics`\n\n**Recht in dealsky:** `outreach.campaigns.view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Erster Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich",
              "format": "date"
            },
            "description": "Erster Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Letzter Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich",
              "format": "date"
            },
            "description": "Letzter Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich"
          },
          {
            "name": "account_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur dieses LinkedIn-Konto (siehe /v1/linkedin/accounts)",
              "format": "uuid"
            },
            "description": "Nur dieses LinkedIn-Konto (siehe /v1/linkedin/accounts)"
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur diese Kampagne (siehe /v1/campaigns)",
              "format": "uuid"
            },
            "description": "Nur diese Kampagne (siehe /v1/campaigns)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "timezone": "Europe/Berlin",
                          "from": "2026-10-12",
                          "to": "2026-10-14",
                          "filters": {
                            "account_id": "4c1d2e3f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                            "campaign_id": null
                          },
                          "days": [
                            {
                              "date": "2026-10-12",
                              "connections_sent": 0,
                              "new_connections": 2,
                              "messages_sent": 0,
                              "replies": 0
                            },
                            {
                              "date": "2026-10-13",
                              "connections_sent": 18,
                              "new_connections": 5,
                              "messages_sent": 9,
                              "replies": 2
                            },
                            {
                              "date": "2026-10-14",
                              "connections_sent": 20,
                              "new_connections": 7,
                              "messages_sent": 11,
                              "replies": 1
                            }
                          ],
                          "totals": {
                            "connections_sent": 38,
                            "new_connections": 14,
                            "messages_sent": 20,
                            "replies": 3
                          }
                        }
                      ],
                      "properties": {
                        "timezone": {
                          "type": "string",
                          "description": "Zeitzone der Tagesgrenzen, immer Europe/Berlin"
                        },
                        "from": {
                          "type": "string",
                          "description": "Erster Tag (einschließlich); ohne Angabe 29 Tage vor to",
                          "format": "date"
                        },
                        "to": {
                          "type": "string",
                          "description": "Letzter Tag (einschließlich); ohne Angabe heute",
                          "format": "date"
                        },
                        "filters": {
                          "type": "object",
                          "description": "Filter, mit denen gerechnet wurde",
                          "properties": {
                            "account_id": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Angewendeter Kontofilter aus der Query, null ohne Filter",
                              "format": "uuid"
                            },
                            "campaign_id": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Angewendeter Kampagnenfilter aus der Query, null ohne Filter",
                              "format": "uuid"
                            }
                          },
                          "additionalProperties": false
                        },
                        "days": {
                          "type": "array",
                          "description": "Jeder Tag des Zeitraums, auch ohne Werte",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string",
                                "description": "Kalendertag (JJJJ-MM-TT, deutsche Zeit)",
                                "format": "date"
                              },
                              "connections_sent": {
                                "type": "integer",
                                "description": "Leads, an die an diesem Tag eine Vernetzungsanfrage ging"
                              },
                              "new_connections": {
                                "type": "integer",
                                "description": "Neu vernetzte Sequenz-Einträge (Karte „Neue Kontakte / Tag“)"
                              },
                              "messages_sent": {
                                "type": "integer",
                                "description": "Gesendete Nachrichten (Text, Sprache, Video, InMail)"
                              },
                              "replies": {
                                "type": "integer",
                                "description": "Eingegangene Antworten (erste Antwort je Sequenz-Eintrag)"
                              }
                            },
                            "additionalProperties": false
                          }
                        },
                        "totals": {
                          "type": "object",
                          "description": "Summe der Tage",
                          "properties": {
                            "connections_sent": {
                              "type": "integer",
                              "description": "Summe der Vernetzungsanfragen aller Tage"
                            },
                            "new_connections": {
                              "type": "integer",
                              "description": "Summe der neuen Kontakte aller Tage"
                            },
                            "messages_sent": {
                              "type": "integer",
                              "description": "Summe der gesendeten Nachrichten aller Tage"
                            },
                            "replies": {
                              "type": "integer",
                              "description": "Summe der Antworten aller Tage"
                            }
                          },
                          "additionalProperties": false
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Drei Tage eines Kontos",
                    "value": {
                      "ok": true,
                      "data": {
                        "timezone": "Europe/Berlin",
                        "from": "2026-10-12",
                        "to": "2026-10-14",
                        "filters": {
                          "account_id": "4c1d2e3f-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                          "campaign_id": null
                        },
                        "days": [
                          {
                            "date": "2026-10-12",
                            "connections_sent": 0,
                            "new_connections": 2,
                            "messages_sent": 0,
                            "replies": 0
                          },
                          {
                            "date": "2026-10-13",
                            "connections_sent": 18,
                            "new_connections": 5,
                            "messages_sent": 9,
                            "replies": 2
                          },
                          {
                            "date": "2026-10-14",
                            "connections_sent": 20,
                            "new_connections": 7,
                            "messages_sent": 11,
                            "replies": 1
                          }
                        ],
                        "totals": {
                          "connections_sent": 38,
                          "new_connections": 14,
                          "messages_sent": 20,
                          "replies": 3
                        }
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:analytics",
        "x-dealsky-permission": "outreach.campaigns.view",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/analytics/activity": {
      "get": {
        "operationId": "listAnalyticsActivity",
        "tags": [
          "Auswertung"
        ],
        "summary": "Aktivitäten-Feed",
        "description": "Neueste zuerst, wie die Aktivitäten der App: Ereignisse aus dem Verlauf der Leads (LinkedIn-Anfragen, Annahmen, Nachrichten, Antworten, Notizen, Statuswechsel) und aus dem Tracking (Landingpage, Video, Buttons, Buchungen, E-Mail). `types` filtert auf bestimmte Arten. Mit `account_id` oder `campaign_id` nur Ereignisse von Leads, die über dieses Konto bzw. in dieser Kampagne laufen. Inhalte von Nachrichten und Notizen stehen nicht im Feed (wie in der App); den Verlauf eines Leads liefert GET /v1/leads/{id}/activities. Wer nicht Inhaber oder Admin ist, sieht nur Ereignisse von Leads auf eigenen LinkedIn-Konten.\n\n**Berechtigung:** `read:analytics`\n\n**Recht in dealsky:** `outreach.campaigns.view` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Erster Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich",
              "format": "date"
            },
            "description": "Erster Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Letzter Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich",
              "format": "date"
            },
            "description": "Letzter Tag (JJJJ-MM-TT, deutsche Zeit), einschließlich"
          },
          {
            "name": "account_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur dieses LinkedIn-Konto (siehe /v1/linkedin/accounts)",
              "format": "uuid"
            },
            "description": "Nur dieses LinkedIn-Konto (siehe /v1/linkedin/accounts)"
          },
          {
            "name": "campaign_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Nur diese Kampagne (siehe /v1/campaigns)",
              "format": "uuid"
            },
            "description": "Nur diese Kampagne (siehe /v1/campaigns)"
          },
          {
            "name": "types",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Eine oder mehrere Arten, kommagetrennt, z. B. linkedin_reply_received,booking_confirmed",
              "items": {
                "type": "string",
                "maxLength": 100
              },
              "maxItems": 50
            },
            "description": "Eine oder mehrere Arten, kommagetrennt, z. B. linkedin_reply_received,booking_confirmed",
            "style": "form",
            "explode": false
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "act-0f1e2d3c-4b5a-4968-8776-655443322110",
                            "source": "activity",
                            "type": "linkedin_reply_received",
                            "occurred_at": "2026-10-18T08:41:12.000Z",
                            "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                            "lead_name": "Max Mustermann",
                            "company": "Beispiel GmbH"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Eindeutig im Feed; act-… aus dem Lead-Verlauf, evt-… aus dem Tracking"
                          },
                          "source": {
                            "type": "string",
                            "description": "activity = Verlauf des Leads (LinkedIn, Notizen, Status), tracking = Landingpage und E-Mail",
                            "enum": [
                              "activity",
                              "tracking"
                            ]
                          },
                          "type": {
                            "type": "string",
                            "description": "Art, z. B. linkedin_connection_sent, linkedin_connection_accepted, linkedin_message_sent, linkedin_reply_received, pageview, video_start, cta_clicked, booking_confirmed"
                          },
                          "occurred_at": {
                            "type": "string",
                            "description": "Zeitpunkt des Ereignisses",
                            "format": "date-time"
                          },
                          "lead_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Lead des Ereignisses (für GET /v1/leads/{id}), null ohne Lead-Bezug",
                            "format": "uuid"
                          },
                          "lead_name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Name des Leads, null, wenn unbekannt"
                          },
                          "company": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Firma des Leads, null, wenn unbekannt"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Neueste Ereignisse einer Kampagne",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "act-0f1e2d3c-4b5a-4968-8776-655443322110",
                          "source": "activity",
                          "type": "linkedin_reply_received",
                          "occurred_at": "2026-10-18T08:41:12.000Z",
                          "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                          "lead_name": "Max Mustermann",
                          "company": "Beispiel GmbH"
                        },
                        {
                          "id": "evt-1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                          "source": "tracking",
                          "type": "pageview",
                          "occurred_at": "2026-10-18T07:55:03.000Z",
                          "lead_id": "6c1d2f8b-4a2e-4b63-8d2f-9b8e3c7a5f21",
                          "lead_name": "Erika Beispiel",
                          "company": "Muster AG"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:analytics",
        "x-dealsky-permission": "outreach.campaigns.view",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "tags": [
          "Webhooks"
        ],
        "summary": "Webhook-Endpunkte auflisten",
        "description": "Alle Webhook-Endpunkte des Kontos, neueste zuerst, wie unter Einstellungen, Integrationen, Webhooks in der App. Auch die in der App angelegten. Das Geheimnis für die Signatur wird hier nie ausgegeben.\n\n**Berechtigung:** `read:webhooks`\n\n**Recht in dealsky:** `settings.integrations` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "active",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Nur aktive (true) oder nur ausgeschaltete (false)"
            },
            "description": "Nur aktive (true) oder nur ausgeschaltete (false)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "4e5f6a7b-8c9d-4e0f-8a1b-2c3d4e5f6a7b",
                            "name": "CRM Sync",
                            "url": "https://hooks.beispiel.de/dealsky",
                            "events": [
                              "linkedin.connection_accepted",
                              "linkedin.replied"
                            ],
                            "active": true,
                            "events_without_trigger": [],
                            "total_deliveries": 128,
                            "successful_deliveries": 126,
                            "failed_deliveries": 2,
                            "last_triggered_at": "2026-10-18T12:02:00.000Z",
                            "last_success_at": "2026-10-18T12:02:00.000Z",
                            "last_failure_at": "2026-10-12T07:15:00.000Z",
                            "created_at": "2026-09-30T14:00:00.000Z",
                            "updated_at": "2026-09-30T14:00:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Webhook-Endpunkts",
                            "readOnly": true,
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Anzeigename in der App"
                          },
                          "url": {
                            "type": "string",
                            "description": "Zieladresse"
                          },
                          "events": {
                            "type": "array",
                            "description": "Abonnierte Ereignisse. Endpunkte aus der App können auch Ereignisse enthalten, die nie gesendet werden (siehe events_without_trigger)",
                            "items": {
                              "type": "string"
                            }
                          },
                          "active": {
                            "type": "boolean",
                            "description": "Nur aktive Endpunkte bekommen Ereignisse (Schalter in der App)"
                          },
                          "events_without_trigger": {
                            "type": "array",
                            "description": "Abonnierte Ereignisse, die dealsky derzeit nie sendet (in der App auswählbar, aber ohne Auslöser)",
                            "readOnly": true,
                            "items": {
                              "type": "string"
                            }
                          },
                          "total_deliveries": {
                            "type": "integer",
                            "description": "Zustellversuche insgesamt",
                            "readOnly": true
                          },
                          "successful_deliveries": {
                            "type": "integer",
                            "description": "davon mit Antwort 2xx",
                            "readOnly": true
                          },
                          "failed_deliveries": {
                            "type": "integer",
                            "description": "davon fehlgeschlagen (kein 2xx oder nicht erreichbar)",
                            "readOnly": true
                          },
                          "last_triggered_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzter Zustellversuch, null, solange noch keiner stattfand",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "last_success_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzte erfolgreiche Zustellung (Antwort 2xx), sonst null",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "last_failure_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Letzte fehlgeschlagene Zustellung, sonst null",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Zeitpunkt der Anlage",
                            "readOnly": true,
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": "string",
                            "description": "Zeitpunkt der letzten Änderung, ohne eigenen Wert der Zeitpunkt der Anlage",
                            "readOnly": true,
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "4e5f6a7b-8c9d-4e0f-8a1b-2c3d4e5f6a7b",
                          "name": "CRM Sync",
                          "url": "https://hooks.beispiel.de/dealsky",
                          "events": [
                            "linkedin.connection_accepted",
                            "linkedin.replied"
                          ],
                          "active": true,
                          "events_without_trigger": [],
                          "total_deliveries": 128,
                          "successful_deliveries": 126,
                          "failed_deliveries": 2,
                          "last_triggered_at": "2026-10-18T12:02:00.000Z",
                          "last_success_at": "2026-10-18T12:02:00.000Z",
                          "last_failure_at": "2026-10-12T07:15:00.000Z",
                          "created_at": "2026-09-30T14:00:00.000Z",
                          "updated_at": "2026-09-30T14:00:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:webhooks",
        "x-dealsky-permission": "settings.integrations",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      },
      "post": {
        "operationId": "createWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Webhook-Endpunkt anlegen",
        "description": "Legt einen Endpunkt an wie „Webhook hinzufügen“ in der App: aktiv, mit eigenem Geheimnis für die Signatur. **Das Geheimnis steht nur in dieser Antwort** (`secret`), über die API danach nie wieder; bitte sofort sicher speichern. Höchstens 10 Endpunkte je Konto, wie in der App (sonst 422 mit `details.reason = \"limit_reached\"`). Fehlt `name`, wird der Hostname der Adresse genommen.\n\n**Adresse:** nur öffentliche `https://`-Adressen bis 2048 Zeichen. Abgelehnt werden IP-Adressen (auch in Dezimal- oder Hex-Schreibweise), `localhost`, `.local`, `.internal` und Adressen mit Zugangsdaten. dealsky ruft die Adresse beim Anlegen nicht auf.\n\nZustellbare Ereignisse: `landing_page.visited`, `booking.confirmed`, `landing_page.deletion_requested`, `linkedin.connection_accepted`, `linkedin.connection_declined`, `linkedin.replied`. Andere Häkchen der App (E-Mail, Brief, Video gestartet, Video 50 %, Video komplett, Buchungsseite geöffnet, Hot Lead) haben derzeit keinen Auslöser und werden darum hier nicht angenommen.\n\n**Zustellung:** dealsky schickt jedes Ereignis einmal per `POST` mit `Content-Type: application/json` an jede aktive, passende Adresse. Es gibt keinen erneuten Versuch. Antwortet die Adresse nicht mit 2xx, zählt das als fehlgeschlagen (`failed_deliveries`, Zustellprotokoll in der App). Bitte schnell mit 2xx antworten und die Arbeit danach erledigen. Die Zustellung übernimmt dieselbe Stelle wie für Webhooks aus der App; diese API legt nur die Endpunkte an.\n\n**Header:** `X-Webhook-Signature` (Signatur, Hex), `X-Webhook-Event` (Name des Ereignisses), `X-Webhook-Timestamp` (Zeitpunkt, derselbe Wert wie `timestamp` im Body).\n\n**Nutzlast:** `{ \"event\", \"timestamp\", \"tenant_id\", \"data\" }`. In `data` stehen `lead_id`, je nach Ereignis `lead_name` und `company_name`, die Einzelheiten in `event_details` und, wenn ein Lead bekannt ist, der ganze Lead in `lead`. Beispiele je Ereignis: GET /v1/webhooks/events.\n\n**Signatur prüfen:** HMAC-SHA256 über den unveränderten Body (die Bytes, wie sie ankommen, nicht neu serialisiert), Schlüssel ist das Geheimnis aus der Antwort von POST /v1/webhooks als Text (UTF-8, die 64 Zeichen selbst, nicht hex-dekodiert). Das Ergebnis als Hex in Kleinbuchstaben muss `X-Webhook-Signature` gleichen; zeitkonstant vergleichen. Der Zeitstempel-Header ist nicht signiert, `timestamp` im Body schon: gegen Wiederholungen den Body-Wert prüfen (z. B. höchstens 5 Minuten alt).\n\nNode.js: `crypto.createHmac(\"sha256\", secret).update(rawBody).digest(\"hex\")`, dann `crypto.timingSafeEqual`. Python: `hmac.compare_digest(hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest(), signature)`.\n\n**Testen:** Einen Test-Aufruf gibt es über die API bewusst nicht (er würde eine fremde Adresse aufrufen). In der App unter Einstellungen, Integrationen, Webhooks schickt „Test“ das erste abonnierte Ereignis des Endpunkts mit `data.test = true`, und zwar an jeden aktiven Endpunkt, der dieses Ereignis abonniert hat. Mit Test-Key wird alles geprüft, aber nichts angelegt und kein Geheimnis erzeugt.\n\nWebhooks sind wie in der App ab dem Growth-Tarif enthalten (sonst 402).\n\n**Berechtigung:** `write:webhooks`\n\n**Recht in dealsky:** `settings.integrations` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Öffentliche https-Adresse, an die dealsky die Ereignisse per POST schickt. Keine IP-Adressen, kein localhost, .local oder .internal, keine Zugangsdaten in der Adresse",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "events": {
                    "type": "array",
                    "description": "Ereignisse, die an diese Adresse gehen. Erlaubt sind nur die, die dealsky heute wirklich sendet: landing_page.visited, booking.confirmed, landing_page.deletion_requested, linkedin.connection_accepted, linkedin.connection_declined, linkedin.replied. Nutzlast je Ereignis: GET /v1/webhooks/events",
                    "items": {
                      "type": "string",
                      "enum": [
                        "landing_page.visited",
                        "booking.confirmed",
                        "landing_page.deletion_requested",
                        "linkedin.connection_accepted",
                        "linkedin.connection_declined",
                        "linkedin.replied"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 20
                  },
                  "name": {
                    "type": "string",
                    "description": "Anzeigename in der App",
                    "maxLength": 200
                  }
                },
                "required": [
                  "url",
                  "events"
                ],
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Beispiel",
                  "value": {
                    "url": "https://hooks.beispiel.de/dealsky",
                    "events": [
                      "booking.confirmed"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nur mit Test-Key: Simulation, es wurde nichts geschrieben (meta.test_mode = true)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Webhook-Endpunkts",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Anzeigename in der App"
                        },
                        "url": {
                          "type": "string",
                          "description": "Zieladresse"
                        },
                        "events": {
                          "type": "array",
                          "description": "Abonnierte Ereignisse. Endpunkte aus der App können auch Ereignisse enthalten, die nie gesendet werden (siehe events_without_trigger)",
                          "items": {
                            "type": "string"
                          }
                        },
                        "active": {
                          "type": "boolean",
                          "description": "Nur aktive Endpunkte bekommen Ereignisse (Schalter in der App)"
                        },
                        "events_without_trigger": {
                          "type": "array",
                          "description": "Abonnierte Ereignisse, die dealsky derzeit nie sendet (in der App auswählbar, aber ohne Auslöser)",
                          "readOnly": true,
                          "items": {
                            "type": "string"
                          }
                        },
                        "total_deliveries": {
                          "type": "integer",
                          "description": "Zustellversuche insgesamt",
                          "readOnly": true
                        },
                        "successful_deliveries": {
                          "type": "integer",
                          "description": "davon mit Antwort 2xx",
                          "readOnly": true
                        },
                        "failed_deliveries": {
                          "type": "integer",
                          "description": "davon fehlgeschlagen (kein 2xx oder nicht erreichbar)",
                          "readOnly": true
                        },
                        "last_triggered_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzter Zustellversuch, null, solange noch keiner stattfand",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "last_success_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte erfolgreiche Zustellung (Antwort 2xx), sonst null",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "last_failure_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte fehlgeschlagene Zustellung, sonst null",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zeitpunkt der letzten Änderung, ohne eigenen Wert der Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "secret": {
                          "type": "string",
                          "description": "Geheimnis für die Signatur (64 Zeichen). Wird NUR in dieser Antwort ausgegeben, danach nie wieder; in der App ist es unter Einstellungen, Integrationen, Webhooks sichtbar",
                          "readOnly": true
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "6a7b8c9d-0e1f-4a2b-9c3d-4e5f6a7b8c9d",
                        "name": "hooks.beispiel.de",
                        "url": "https://hooks.beispiel.de/dealsky",
                        "events": [
                          "booking.confirmed"
                        ],
                        "active": true,
                        "events_without_trigger": [],
                        "total_deliveries": 0,
                        "successful_deliveries": 0,
                        "failed_deliveries": 0,
                        "last_triggered_at": null,
                        "last_success_at": null,
                        "last_failure_at": null,
                        "created_at": "2026-10-18T14:00:00.000Z",
                        "updated_at": "2026-10-18T14:00:00.000Z",
                        "secret": "9f2c4e6a8b0d1f3e5a7c9b1d3f5e7a9c2b4d6f8a0c1e3b5d7f9a2c4e6b8d0f1a"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:webhooks",
        "x-dealsky-permission": "settings.integrations",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/webhooks/events": {
      "get": {
        "operationId": "listWebhookEvents",
        "tags": [
          "Webhooks"
        ],
        "summary": "Ereignisse und ihre Nutzlast",
        "description": "Die Ereignisse, die ein Webhook-Endpunkt abonnieren kann, mit Anlass und einer Beispiel-Nutzlast genau in der Form, in der dealsky sie sendet. Feste Liste, unabhängig vom Konto.\n\nZustellbare Ereignisse: `landing_page.visited`, `booking.confirmed`, `landing_page.deletion_requested`, `linkedin.connection_accepted`, `linkedin.connection_declined`, `linkedin.replied`. Andere Häkchen der App (E-Mail, Brief, Video gestartet, Video 50 %, Video komplett, Buchungsseite geöffnet, Hot Lead) haben derzeit keinen Auslöser und werden darum hier nicht angenommen.\n\n**Berechtigung:** `read:webhooks`\n\n**Recht in dealsky:** `settings.integrations` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "event": {
                            "type": "string",
                            "description": "Name, wie er in events und im Header X-Webhook-Event steht"
                          },
                          "description": {
                            "type": "string",
                            "description": "Wann das Ereignis kommt"
                          },
                          "example": {
                            "type": "object",
                            "description": "Body, wie dealsky ihn per POST schickt",
                            "additionalProperties": true
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "event": "landing_page.visited",
                          "description": "Ein Lead hat seine persönliche Landingpage geöffnet. Kommt bei jedem Seitenaufruf, Bots werden vorher herausgefiltert. Nur wenn das Landingpage-Tracking im Konto eingeschaltet ist.",
                          "example": {
                            "event": "landing_page.visited",
                            "timestamp": "2026-10-18T09:12:00.000Z",
                            "tenant_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                            "data": {
                              "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                              "lead_name": "Max Mustermann",
                              "company_name": "Beispiel GmbH",
                              "event_details": {
                                "slug": "max-mustermann",
                                "landing_page_url": "https://beispiel.dealsky.app/max-mustermann"
                              },
                              "lead": {
                                "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                                "email": "max.mustermann@beispiel.de",
                                "first_name": "Max",
                                "last_name": "Mustermann",
                                "full_name": "Max Mustermann",
                                "salutation": "Herr",
                                "anrede": "Herr",
                                "company": "Beispiel GmbH",
                                "title": "Geschäftsführer",
                                "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                                "phone": "+49 3012 3456",
                                "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                                "website": "https://beispiel.de",
                                "street": "Musterstraße 1",
                                "city": "Berlin",
                                "postal_code": "10115",
                                "country": "DE",
                                "full_address": "Musterstraße 1, 10115 Berlin, DE",
                                "score": 42,
                                "stage": "warm",
                                "status": "contacted",
                                "employees": "11-50",
                                "keywords": null,
                                "landing_page_url": "https://beispiel.dealsky.app/max-mustermann",
                                "personalized_video_url": null,
                                "personalized_video_thumbnail": null,
                                "qr_code_url": null,
                                "logo_url": null,
                                "notes": null,
                                "created_at": "2026-10-01T08:00:00.000Z",
                                "updated_at": "2026-10-18T09:12:00.000Z",
                                "last_activity_at": "2026-10-18T09:12:00.000Z"
                              }
                            }
                          }
                        },
                        {
                          "event": "booking.confirmed",
                          "description": "Ein Lead hat über die Buchungsseite seiner Landingpage einen Termin gebucht (Bestätigungsseite geöffnet). dealsky stoppt dabei laufende Sequenzen dieses Leads.",
                          "example": {
                            "event": "booking.confirmed",
                            "timestamp": "2026-10-18T09:30:00.000Z",
                            "tenant_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                            "data": {
                              "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                              "lead_name": "Max Mustermann",
                              "company_name": "Beispiel GmbH",
                              "event_details": {
                                "slug": "max-mustermann",
                                "landing_page_url": "https://beispiel.dealsky.app/max-mustermann"
                              },
                              "lead": {
                                "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                                "email": "max.mustermann@beispiel.de",
                                "first_name": "Max",
                                "last_name": "Mustermann",
                                "full_name": "Max Mustermann",
                                "salutation": "Herr",
                                "anrede": "Herr",
                                "company": "Beispiel GmbH",
                                "title": "Geschäftsführer",
                                "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                                "phone": "+49 3012 3456",
                                "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                                "website": "https://beispiel.de",
                                "street": "Musterstraße 1",
                                "city": "Berlin",
                                "postal_code": "10115",
                                "country": "DE",
                                "full_address": "Musterstraße 1, 10115 Berlin, DE",
                                "score": 42,
                                "stage": "warm",
                                "status": "contacted",
                                "employees": "11-50",
                                "keywords": null,
                                "landing_page_url": "https://beispiel.dealsky.app/max-mustermann",
                                "personalized_video_url": null,
                                "personalized_video_thumbnail": null,
                                "qr_code_url": null,
                                "logo_url": null,
                                "notes": null,
                                "created_at": "2026-10-01T08:00:00.000Z",
                                "updated_at": "2026-10-18T09:12:00.000Z",
                                "last_activity_at": "2026-10-18T09:12:00.000Z"
                              }
                            }
                          }
                        },
                        {
                          "event": "landing_page.deletion_requested",
                          "description": "Ein Lead hat auf seiner Landingpage die Löschung seiner Daten beantragt. dealsky vermerkt den Antrag am Lead; gelöscht wird erst, wenn das Konto es tut.",
                          "example": {
                            "event": "landing_page.deletion_requested",
                            "timestamp": "2026-10-18T10:05:00.000Z",
                            "tenant_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                            "data": {
                              "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                              "lead_name": "Max Mustermann",
                              "company_name": "Beispiel GmbH",
                              "event_details": {
                                "landing_page_url": "https://beispiel.dealsky.app/max-mustermann",
                                "requested_at": "2026-10-18T10:05:00.000Z"
                              },
                              "lead": {
                                "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                                "email": "max.mustermann@beispiel.de",
                                "first_name": "Max",
                                "last_name": "Mustermann",
                                "full_name": "Max Mustermann",
                                "salutation": "Herr",
                                "anrede": "Herr",
                                "company": "Beispiel GmbH",
                                "title": "Geschäftsführer",
                                "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                                "phone": "+49 3012 3456",
                                "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                                "website": "https://beispiel.de",
                                "street": "Musterstraße 1",
                                "city": "Berlin",
                                "postal_code": "10115",
                                "country": "DE",
                                "full_address": "Musterstraße 1, 10115 Berlin, DE",
                                "score": 42,
                                "stage": "warm",
                                "status": "contacted",
                                "employees": "11-50",
                                "keywords": null,
                                "landing_page_url": "https://beispiel.dealsky.app/max-mustermann",
                                "personalized_video_url": null,
                                "personalized_video_thumbnail": null,
                                "qr_code_url": null,
                                "logo_url": null,
                                "notes": null,
                                "created_at": "2026-10-01T08:00:00.000Z",
                                "updated_at": "2026-10-18T09:12:00.000Z",
                                "last_activity_at": "2026-10-18T09:12:00.000Z"
                              }
                            }
                          }
                        },
                        {
                          "event": "linkedin.connection_accepted",
                          "description": "Ein Lead hat eine Vernetzungsanfrage aus einer Kampagne angenommen. Kommt einmal je Lead und Sequenz, egal ob LinkedIn die Annahme meldet (detection_source webhook) oder dealsky sie beim Abgleich findet (polling, inline_check).",
                          "example": {
                            "event": "linkedin.connection_accepted",
                            "timestamp": "2026-10-18T11:20:00.000Z",
                            "tenant_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                            "data": {
                              "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                              "event_details": {
                                "sequence_id": "2c3d4e5f-6a7b-4c8d-9e0f-1a2b3c4d5e6f",
                                "detection_source": "webhook",
                                "match_method": "profile_id"
                              },
                              "lead": {
                                "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                                "email": "max.mustermann@beispiel.de",
                                "first_name": "Max",
                                "last_name": "Mustermann",
                                "full_name": "Max Mustermann",
                                "salutation": "Herr",
                                "anrede": "Herr",
                                "company": "Beispiel GmbH",
                                "title": "Geschäftsführer",
                                "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                                "phone": "+49 3012 3456",
                                "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                                "website": "https://beispiel.de",
                                "street": "Musterstraße 1",
                                "city": "Berlin",
                                "postal_code": "10115",
                                "country": "DE",
                                "full_address": "Musterstraße 1, 10115 Berlin, DE",
                                "score": 42,
                                "stage": "warm",
                                "status": "contacted",
                                "employees": "11-50",
                                "keywords": null,
                                "landing_page_url": "https://beispiel.dealsky.app/max-mustermann",
                                "personalized_video_url": null,
                                "personalized_video_thumbnail": null,
                                "qr_code_url": null,
                                "logo_url": null,
                                "notes": null,
                                "created_at": "2026-10-01T08:00:00.000Z",
                                "updated_at": "2026-10-18T09:12:00.000Z",
                                "last_activity_at": "2026-10-18T09:12:00.000Z"
                              }
                            }
                          }
                        },
                        {
                          "event": "linkedin.connection_declined",
                          "description": "LinkedIn meldet, dass ein Lead eine Vernetzungsanfrage abgelehnt hat, auf die eine Kampagne gerade wartet. Die Sequenz endet für diesen Lead.",
                          "example": {
                            "event": "linkedin.connection_declined",
                            "timestamp": "2026-10-18T11:45:00.000Z",
                            "tenant_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                            "data": {
                              "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                              "event_details": {
                                "profile_id": "ACoAAB1x2y3z4A5b6C7d8E9f0G"
                              },
                              "lead": {
                                "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                                "email": "max.mustermann@beispiel.de",
                                "first_name": "Max",
                                "last_name": "Mustermann",
                                "full_name": "Max Mustermann",
                                "salutation": "Herr",
                                "anrede": "Herr",
                                "company": "Beispiel GmbH",
                                "title": "Geschäftsführer",
                                "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                                "phone": "+49 3012 3456",
                                "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                                "website": "https://beispiel.de",
                                "street": "Musterstraße 1",
                                "city": "Berlin",
                                "postal_code": "10115",
                                "country": "DE",
                                "full_address": "Musterstraße 1, 10115 Berlin, DE",
                                "score": 42,
                                "stage": "warm",
                                "status": "contacted",
                                "employees": "11-50",
                                "keywords": null,
                                "landing_page_url": "https://beispiel.dealsky.app/max-mustermann",
                                "personalized_video_url": null,
                                "personalized_video_thumbnail": null,
                                "qr_code_url": null,
                                "logo_url": null,
                                "notes": null,
                                "created_at": "2026-10-01T08:00:00.000Z",
                                "updated_at": "2026-10-18T09:12:00.000Z",
                                "last_activity_at": "2026-10-18T09:12:00.000Z"
                              }
                            }
                          }
                        },
                        {
                          "event": "linkedin.replied",
                          "description": "Auf einem verbundenen LinkedIn-Konto ist eine Nachricht eingegangen. lead_id ist null und lead fehlt, wenn dealsky den Absender keinem Lead zuordnen konnte. Meldet LinkedIn eine Nachricht doppelt, kommt auch das Ereignis doppelt; zum Entdoppeln event_details.message_id nutzen.",
                          "example": {
                            "event": "linkedin.replied",
                            "timestamp": "2026-10-18T12:02:00.000Z",
                            "tenant_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                            "data": {
                              "lead_id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                              "event_details": {
                                "chat_id": "1rT5vX9zQ2mN4bL6",
                                "message_id": "8kP3sW7yD1fH5jC9",
                                "message_preview": "Hallo Herr Schmidt, danke für die Nachricht. Passt Ihnen Donnerstag?"
                              },
                              "lead": {
                                "id": "5b0c1e7a-3f1d-4a52-9c1e-8a7d2b6f4e10",
                                "email": "max.mustermann@beispiel.de",
                                "first_name": "Max",
                                "last_name": "Mustermann",
                                "full_name": "Max Mustermann",
                                "salutation": "Herr",
                                "anrede": "Herr",
                                "company": "Beispiel GmbH",
                                "title": "Geschäftsführer",
                                "headline": "Geschäftsführer bei Beispiel GmbH | Digitalisierung im Mittelstand",
                                "phone": "+49 3012 3456",
                                "linkedin_url": "https://www.linkedin.com/in/max-mustermann",
                                "website": "https://beispiel.de",
                                "street": "Musterstraße 1",
                                "city": "Berlin",
                                "postal_code": "10115",
                                "country": "DE",
                                "full_address": "Musterstraße 1, 10115 Berlin, DE",
                                "score": 42,
                                "stage": "warm",
                                "status": "contacted",
                                "employees": "11-50",
                                "keywords": null,
                                "landing_page_url": "https://beispiel.dealsky.app/max-mustermann",
                                "personalized_video_url": null,
                                "personalized_video_thumbnail": null,
                                "qr_code_url": null,
                                "logo_url": null,
                                "notes": null,
                                "created_at": "2026-10-01T08:00:00.000Z",
                                "updated_at": "2026-10-18T09:12:00.000Z",
                                "last_activity_at": "2026-10-18T09:12:00.000Z"
                              }
                            }
                          }
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:webhooks",
        "x-dealsky-permission": "settings.integrations",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/webhooks/{id}": {
      "get": {
        "operationId": "getWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Einen Webhook-Endpunkt abrufen",
        "description": "Endpunkt mit Zustell-Statistik. Das Geheimnis für die Signatur wird hier nie ausgegeben.\n\n**Berechtigung:** `read:webhooks`\n\n**Recht in dealsky:** `settings.integrations` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Webhook-Endpunkts",
              "format": "uuid"
            },
            "description": "ID des Webhook-Endpunkts"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "4e5f6a7b-8c9d-4e0f-8a1b-2c3d4e5f6a7b",
                          "name": "CRM Sync",
                          "url": "https://hooks.beispiel.de/dealsky",
                          "events": [
                            "linkedin.connection_accepted",
                            "linkedin.replied"
                          ],
                          "active": true,
                          "events_without_trigger": [],
                          "total_deliveries": 128,
                          "successful_deliveries": 126,
                          "failed_deliveries": 2,
                          "last_triggered_at": "2026-10-18T12:02:00.000Z",
                          "last_success_at": "2026-10-18T12:02:00.000Z",
                          "last_failure_at": "2026-10-12T07:15:00.000Z",
                          "created_at": "2026-09-30T14:00:00.000Z",
                          "updated_at": "2026-09-30T14:00:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Webhook-Endpunkts",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Anzeigename in der App"
                        },
                        "url": {
                          "type": "string",
                          "description": "Zieladresse"
                        },
                        "events": {
                          "type": "array",
                          "description": "Abonnierte Ereignisse. Endpunkte aus der App können auch Ereignisse enthalten, die nie gesendet werden (siehe events_without_trigger)",
                          "items": {
                            "type": "string"
                          }
                        },
                        "active": {
                          "type": "boolean",
                          "description": "Nur aktive Endpunkte bekommen Ereignisse (Schalter in der App)"
                        },
                        "events_without_trigger": {
                          "type": "array",
                          "description": "Abonnierte Ereignisse, die dealsky derzeit nie sendet (in der App auswählbar, aber ohne Auslöser)",
                          "readOnly": true,
                          "items": {
                            "type": "string"
                          }
                        },
                        "total_deliveries": {
                          "type": "integer",
                          "description": "Zustellversuche insgesamt",
                          "readOnly": true
                        },
                        "successful_deliveries": {
                          "type": "integer",
                          "description": "davon mit Antwort 2xx",
                          "readOnly": true
                        },
                        "failed_deliveries": {
                          "type": "integer",
                          "description": "davon fehlgeschlagen (kein 2xx oder nicht erreichbar)",
                          "readOnly": true
                        },
                        "last_triggered_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzter Zustellversuch, null, solange noch keiner stattfand",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "last_success_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte erfolgreiche Zustellung (Antwort 2xx), sonst null",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "last_failure_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte fehlgeschlagene Zustellung, sonst null",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zeitpunkt der letzten Änderung, ohne eigenen Wert der Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "4e5f6a7b-8c9d-4e0f-8a1b-2c3d4e5f6a7b",
                        "name": "CRM Sync",
                        "url": "https://hooks.beispiel.de/dealsky",
                        "events": [
                          "linkedin.connection_accepted",
                          "linkedin.replied"
                        ],
                        "active": true,
                        "events_without_trigger": [],
                        "total_deliveries": 128,
                        "successful_deliveries": 126,
                        "failed_deliveries": 2,
                        "last_triggered_at": "2026-10-18T12:02:00.000Z",
                        "last_success_at": "2026-10-18T12:02:00.000Z",
                        "last_failure_at": "2026-10-12T07:15:00.000Z",
                        "created_at": "2026-09-30T14:00:00.000Z",
                        "updated_at": "2026-09-30T14:00:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:webhooks",
        "x-dealsky-permission": "settings.integrations",
        "x-dealsky-risk": "read"
      },
      "patch": {
        "operationId": "updateWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Webhook-Endpunkt ändern oder an- und ausschalten",
        "description": "Nur übergebene Felder werden geändert. `active: false` schaltet den Endpunkt aus wie der Schalter in der App, `events` ersetzt die ganze Liste. Eine neue Adresse wird geprüft wie beim Anlegen. Das Geheimnis bleibt gleich und wird nicht ausgegeben.\n\nZustellbare Ereignisse: `landing_page.visited`, `booking.confirmed`, `landing_page.deletion_requested`, `linkedin.connection_accepted`, `linkedin.connection_declined`, `linkedin.replied`. Andere Häkchen der App (E-Mail, Brief, Video gestartet, Video 50 %, Video komplett, Buchungsseite geöffnet, Hot Lead) haben derzeit keinen Auslöser und werden darum hier nicht angenommen.\n\n**Berechtigung:** `write:webhooks`\n\n**Recht in dealsky:** `settings.integrations` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Webhook-Endpunkts",
              "format": "uuid"
            },
            "description": "ID des Webhook-Endpunkts"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Anzeigename in der App",
                    "maxLength": 200
                  },
                  "url": {
                    "type": "string",
                    "description": "Öffentliche https-Adresse, an die dealsky die Ereignisse per POST schickt. Keine IP-Adressen, kein localhost, .local oder .internal, keine Zugangsdaten in der Adresse",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "events": {
                    "type": "array",
                    "description": "Ereignisse, die an diese Adresse gehen. Erlaubt sind nur die, die dealsky heute wirklich sendet: landing_page.visited, booking.confirmed, landing_page.deletion_requested, linkedin.connection_accepted, linkedin.connection_declined, linkedin.replied. Nutzlast je Ereignis: GET /v1/webhooks/events",
                    "items": {
                      "type": "string",
                      "enum": [
                        "landing_page.visited",
                        "booking.confirmed",
                        "landing_page.deletion_requested",
                        "linkedin.connection_accepted",
                        "linkedin.connection_declined",
                        "linkedin.replied"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 20
                  },
                  "active": {
                    "type": "boolean",
                    "description": "An oder aus"
                  }
                },
                "additionalProperties": false
              },
              "examples": {
                "beispiel1": {
                  "summary": "Ausschalten",
                  "value": {
                    "active": false
                  }
                },
                "beispiel2": {
                  "summary": "Ereignisse ersetzen",
                  "value": {
                    "events": [
                      "linkedin.replied",
                      "booking.confirmed"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "4e5f6a7b-8c9d-4e0f-8a1b-2c3d4e5f6a7b",
                          "name": "CRM Sync",
                          "url": "https://hooks.beispiel.de/dealsky",
                          "events": [
                            "linkedin.connection_accepted",
                            "linkedin.replied"
                          ],
                          "active": true,
                          "events_without_trigger": [],
                          "total_deliveries": 128,
                          "successful_deliveries": 126,
                          "failed_deliveries": 2,
                          "last_triggered_at": "2026-10-18T12:02:00.000Z",
                          "last_success_at": "2026-10-18T12:02:00.000Z",
                          "last_failure_at": "2026-10-12T07:15:00.000Z",
                          "created_at": "2026-09-30T14:00:00.000Z",
                          "updated_at": "2026-09-30T14:00:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Webhook-Endpunkts",
                          "readOnly": true,
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Anzeigename in der App"
                        },
                        "url": {
                          "type": "string",
                          "description": "Zieladresse"
                        },
                        "events": {
                          "type": "array",
                          "description": "Abonnierte Ereignisse. Endpunkte aus der App können auch Ereignisse enthalten, die nie gesendet werden (siehe events_without_trigger)",
                          "items": {
                            "type": "string"
                          }
                        },
                        "active": {
                          "type": "boolean",
                          "description": "Nur aktive Endpunkte bekommen Ereignisse (Schalter in der App)"
                        },
                        "events_without_trigger": {
                          "type": "array",
                          "description": "Abonnierte Ereignisse, die dealsky derzeit nie sendet (in der App auswählbar, aber ohne Auslöser)",
                          "readOnly": true,
                          "items": {
                            "type": "string"
                          }
                        },
                        "total_deliveries": {
                          "type": "integer",
                          "description": "Zustellversuche insgesamt",
                          "readOnly": true
                        },
                        "successful_deliveries": {
                          "type": "integer",
                          "description": "davon mit Antwort 2xx",
                          "readOnly": true
                        },
                        "failed_deliveries": {
                          "type": "integer",
                          "description": "davon fehlgeschlagen (kein 2xx oder nicht erreichbar)",
                          "readOnly": true
                        },
                        "last_triggered_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzter Zustellversuch, null, solange noch keiner stattfand",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "last_success_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte erfolgreiche Zustellung (Antwort 2xx), sonst null",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "last_failure_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Letzte fehlgeschlagene Zustellung, sonst null",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "created_at": {
                          "type": "string",
                          "description": "Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "description": "Zeitpunkt der letzten Änderung, ohne eigenen Wert der Zeitpunkt der Anlage",
                          "readOnly": true,
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Ausschalten",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "4e5f6a7b-8c9d-4e0f-8a1b-2c3d4e5f6a7b",
                        "name": "CRM Sync",
                        "url": "https://hooks.beispiel.de/dealsky",
                        "events": [
                          "linkedin.connection_accepted",
                          "linkedin.replied"
                        ],
                        "active": false,
                        "events_without_trigger": [],
                        "total_deliveries": 128,
                        "successful_deliveries": 126,
                        "failed_deliveries": 2,
                        "last_triggered_at": "2026-10-18T12:02:00.000Z",
                        "last_success_at": "2026-10-18T12:02:00.000Z",
                        "last_failure_at": "2026-10-12T07:15:00.000Z",
                        "created_at": "2026-09-30T14:00:00.000Z",
                        "updated_at": "2026-09-30T14:00:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Ereignisse ersetzen",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "4e5f6a7b-8c9d-4e0f-8a1b-2c3d4e5f6a7b",
                        "name": "CRM Sync",
                        "url": "https://hooks.beispiel.de/dealsky",
                        "events": [
                          "linkedin.replied",
                          "booking.confirmed"
                        ],
                        "active": true,
                        "events_without_trigger": [],
                        "total_deliveries": 128,
                        "successful_deliveries": 126,
                        "failed_deliveries": 2,
                        "last_triggered_at": "2026-10-18T12:02:00.000Z",
                        "last_success_at": "2026-10-18T12:02:00.000Z",
                        "last_failure_at": "2026-10-12T07:15:00.000Z",
                        "created_at": "2026-09-30T14:00:00.000Z",
                        "updated_at": "2026-09-30T14:00:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "409": {
            "$ref": "#/components/responses/CONFLICT"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:webhooks",
        "x-dealsky-permission": "settings.integrations",
        "x-dealsky-risk": "write"
      },
      "delete": {
        "operationId": "deleteWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Webhook-Endpunkt löschen",
        "description": "Löscht den Endpunkt wie „Löschen“ in der App, samt seinem Zustellprotokoll. Danach gehen keine Ereignisse mehr an die Adresse. Zapier-Verbindungen sind davon nicht betroffen. Wer nur pausieren will, nutzt PATCH mit `active: false`.\n\n**Berechtigung:** `write:webhooks`\n\n**Recht in dealsky:** `settings.integrations` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Ändert Daten im Konto.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Webhook-Endpunkts",
              "format": "uuid"
            },
            "description": "ID des Webhook-Endpunkts"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": {
                          "type": "boolean",
                          "description": "true: Der Endpunkt wurde gelöscht"
                        },
                        "id": {
                          "type": "string",
                          "description": "ID des gelöschten Endpunkts",
                          "format": "uuid"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "deleted": true,
                        "id": "4e5f6a7b-8c9d-4e0f-8a1b-2c3d4e5f6a7b"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "write:webhooks",
        "x-dealsky-permission": "settings.integrations",
        "x-dealsky-risk": "write"
      }
    },
    "/v1/booking-links": {
      "get": {
        "operationId": "listBookingLinks",
        "tags": [
          "Einstellungen"
        ],
        "summary": "Buchungslinks auflisten",
        "description": "Die Buchungslinks des Kontos (Kalender von Calendly, TidyCal, Cal.com oder eigene Buchungsseiten), wie sie unter Einrichtung, Kalender und im Termin-Menü des Postfachs stehen. Standard-Kalender zuerst, dann nach Name. Kostet nichts.\n\n`url` ist die Adresse, die die App beim Öffnen und Kopieren nimmt; bei eingebetteten Kalendern liest sie die API aus dem Embed-Code. Für eine vorausgefüllte Buchungsseite wie beim Kopieren aus dem Postfach können `name`, `first_name`, `last_name`, `email` und `company` als Query-Parameter angehängt werden (Calendly, TidyCal und Cal.com lesen `name` und `email`). Direktbuchungs-Kalender (`tidycal_direct`, `calendly_direct`) haben keinen öffentlichen Link (`url` ist null) und sind nur in der App buchbar.\n\nFür Nachrichten an Leads sind die Links mit `show_in_inbox = true` gedacht: Die gibt der Kunde für das Postfach frei. Recht wie in der App: Wer das Postfach öffnen darf (`outreach.inbox`), sieht dort alle Buchungslinks. Zugangsdaten zu Kalendern und den Embed-Code gibt die API nicht heraus. Anlegen und ändern geht nur in der App.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "description": "Einträge pro Seite (Standard 25, höchstens 100)",
              "examples": [
                25
              ],
              "minimum": 1,
              "maximum": 100
            },
            "description": "Einträge pro Seite (Standard 25, höchstens 100)"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Wert aus meta.next_cursor der vorigen Seite",
              "maxLength": 200
            },
            "description": "Wert aus meta.next_cursor der vorigen Seite"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Eine oder mehrere Kategorien, kommagetrennt. landingpage enthält auch alte Einträge ohne Kategorie",
              "items": {
                "type": "string",
                "enum": [
                  "landingpage",
                  "oncall",
                  "inbox"
                ]
              },
              "maxItems": 3
            },
            "description": "Eine oder mehrere Kategorien, kommagetrennt. landingpage enthält auch alte Einträge ohne Kategorie",
            "style": "form",
            "explode": false
          },
          {
            "name": "calendar_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "description": "Eine oder mehrere Arten, kommagetrennt, z. B. link,embed (die mit öffentlichem Link)",
              "items": {
                "type": "string",
                "enum": [
                  "link",
                  "embed",
                  "tidycal_direct",
                  "calendly_direct"
                ]
              },
              "maxItems": 4
            },
            "description": "Eine oder mehrere Arten, kommagetrennt, z. B. link,embed (die mit öffentlichem Link)",
            "style": "form",
            "explode": false
          },
          {
            "name": "show_in_inbox",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Nur Links, die für das Postfach freigegeben sind (true) bzw. nicht (false)"
            },
            "description": "Nur Links, die für das Postfach freigegeben sind (true) bzw. nicht (false)"
          },
          {
            "name": "show_in_crm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Nur Links, die im Lead-Panel zur Direktbuchung freigegeben sind (true) bzw. nicht (false)"
            },
            "description": "Nur Links, die im Lead-Panel zur Direktbuchung freigegeben sind (true) bzw. nicht (false)"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "examples": [
                          {
                            "id": "4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b",
                            "name": "Erstgespräch 30 Minuten",
                            "calendar_type": "link",
                            "url": "https://calendly.com/beispiel-gmbh/erstgespraech",
                            "category": "landingpage",
                            "is_default": true,
                            "show_in_crm": false,
                            "show_in_inbox": true,
                            "created_at": "2026-09-02T10:15:00.000Z",
                            "updated_at": "2026-10-01T08:30:00.000Z"
                          }
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "ID des Buchungslinks",
                            "format": "uuid"
                          },
                          "name": {
                            "type": "string",
                            "description": "Name, wie er in der App steht"
                          },
                          "calendar_type": {
                            "type": "string",
                            "description": "Art: link (externe Buchungsseite), embed (eingebetteter Kalender), tidycal_direct oder calendly_direct (Direktbuchung in der App, ohne öffentlichen Link)",
                            "enum": [
                              "link",
                              "embed",
                              "tidycal_direct",
                              "calendly_direct"
                            ]
                          },
                          "url": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Öffentliche Buchungsseite, wie die App sie öffnet und kopiert (bei embed aus dem Embed-Code gelesen). null, wenn es keine gibt, z. B. bei Direktbuchung"
                          },
                          "category": {
                            "type": "string",
                            "description": "landingpage: Kalender für Landingpages und Lead-Panel, oncall: Telefon-Termine, inbox: nur im Termin-Menü des Postfachs angelegt",
                            "enum": [
                              "landingpage",
                              "oncall",
                              "inbox"
                            ]
                          },
                          "is_default": {
                            "type": "boolean",
                            "description": "Standard-Kalender der Landingpages"
                          },
                          "show_in_crm": {
                            "type": "boolean",
                            "description": "Im Lead-Panel zur Direktbuchung freigegeben"
                          },
                          "show_in_inbox": {
                            "type": "boolean",
                            "description": "Im Termin-Menü des Postfachs freigegeben. Für Nachrichten an Leads sind das die Links, die der Kunde dafür vorgesehen hat"
                          },
                          "created_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der Anlage",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Zeitpunkt der letzten Änderung",
                            "format": "date-time"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        },
                        "next_cursor": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Für die nächste Seite als ?cursor= übergeben"
                        },
                        "has_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Alle Buchungslinks",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b",
                          "name": "Erstgespräch 30 Minuten",
                          "calendar_type": "link",
                          "url": "https://calendly.com/beispiel-gmbh/erstgespraech",
                          "category": "landingpage",
                          "is_default": true,
                          "show_in_crm": false,
                          "show_in_inbox": true,
                          "created_at": "2026-09-02T10:15:00.000Z",
                          "updated_at": "2026-10-01T08:30:00.000Z"
                        },
                        {
                          "id": "5f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c",
                          "name": "Demo mit Anna",
                          "calendar_type": "embed",
                          "url": "https://cal.com/anna-beispiel/demo",
                          "category": "landingpage",
                          "is_default": false,
                          "show_in_crm": false,
                          "show_in_inbox": false,
                          "created_at": "2026-09-10T14:00:00.000Z",
                          "updated_at": "2026-09-10T14:00:00.000Z"
                        },
                        {
                          "id": "6a7b8c9d-0e1f-4a2b-9c3d-4e5f6a7b8c9d",
                          "name": "Setting-Call (TidyCal)",
                          "calendar_type": "tidycal_direct",
                          "url": null,
                          "category": "landingpage",
                          "is_default": false,
                          "show_in_crm": true,
                          "show_in_inbox": false,
                          "created_at": "2026-09-12T09:00:00.000Z",
                          "updated_at": "2026-09-12T09:00:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  },
                  "beispiel2": {
                    "summary": "Links für Nachrichten im Postfach",
                    "value": {
                      "ok": true,
                      "data": [
                        {
                          "id": "4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b",
                          "name": "Erstgespräch 30 Minuten",
                          "calendar_type": "link",
                          "url": "https://calendly.com/beispiel-gmbh/erstgespraech",
                          "category": "landingpage",
                          "is_default": true,
                          "show_in_crm": false,
                          "show_in_inbox": true,
                          "created_at": "2026-09-02T10:15:00.000Z",
                          "updated_at": "2026-10-01T08:30:00.000Z"
                        }
                      ],
                      "meta": {
                        "request_id": "req_7f3a…",
                        "next_cursor": null,
                        "has_more": false
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "read",
        "x-dealsky-paginated": true
      }
    },
    "/v1/booking-links/{id}": {
      "get": {
        "operationId": "getBookingLink",
        "tags": [
          "Einstellungen"
        ],
        "summary": "Einen Buchungslink abrufen",
        "description": "Ein Buchungslink mit denselben Feldern wie in der Liste. 404, wenn es die ID im Konto nicht gibt. Kostet nichts.\n\n**Berechtigung:** `read:crm`\n\n**Recht in dealsky:** `outreach.inbox` (die Person, die den Key erzeugt hat, braucht es)\n\n**Wirkung:** Liest nur.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "ID des Buchungslinks",
              "format": "uuid"
            },
            "description": "ID des Buchungslinks"
          }
        ],
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "id": "4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b",
                          "name": "Erstgespräch 30 Minuten",
                          "calendar_type": "link",
                          "url": "https://calendly.com/beispiel-gmbh/erstgespraech",
                          "category": "landingpage",
                          "is_default": true,
                          "show_in_crm": false,
                          "show_in_inbox": true,
                          "created_at": "2026-09-02T10:15:00.000Z",
                          "updated_at": "2026-10-01T08:30:00.000Z"
                        }
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "ID des Buchungslinks",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string",
                          "description": "Name, wie er in der App steht"
                        },
                        "calendar_type": {
                          "type": "string",
                          "description": "Art: link (externe Buchungsseite), embed (eingebetteter Kalender), tidycal_direct oder calendly_direct (Direktbuchung in der App, ohne öffentlichen Link)",
                          "enum": [
                            "link",
                            "embed",
                            "tidycal_direct",
                            "calendly_direct"
                          ]
                        },
                        "url": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Öffentliche Buchungsseite, wie die App sie öffnet und kopiert (bei embed aus dem Embed-Code gelesen). null, wenn es keine gibt, z. B. bei Direktbuchung"
                        },
                        "category": {
                          "type": "string",
                          "description": "landingpage: Kalender für Landingpages und Lead-Panel, oncall: Telefon-Termine, inbox: nur im Termin-Menü des Postfachs angelegt",
                          "enum": [
                            "landingpage",
                            "oncall",
                            "inbox"
                          ]
                        },
                        "is_default": {
                          "type": "boolean",
                          "description": "Standard-Kalender der Landingpages"
                        },
                        "show_in_crm": {
                          "type": "boolean",
                          "description": "Im Lead-Panel zur Direktbuchung freigegeben"
                        },
                        "show_in_inbox": {
                          "type": "boolean",
                          "description": "Im Termin-Menü des Postfachs freigegeben. Für Nachrichten an Leads sind das die Links, die der Kunde dafür vorgesehen hat"
                        },
                        "created_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der Anlage",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Zeitpunkt der letzten Änderung",
                          "format": "date-time"
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "id": "4e5f6a7b-8c9d-4e0f-9a1b-2c3d4e5f6a7b",
                        "name": "Erstgespräch 30 Minuten",
                        "calendar_type": "link",
                        "url": "https://calendly.com/beispiel-gmbh/erstgespraech",
                        "category": "landingpage",
                        "is_default": true,
                        "show_in_crm": false,
                        "show_in_inbox": true,
                        "created_at": "2026-09-02T10:15:00.000Z",
                        "updated_at": "2026-10-01T08:30:00.000Z"
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "404": {
            "$ref": "#/components/responses/NOT_FOUND"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:crm",
        "x-dealsky-permission": "outreach.inbox",
        "x-dealsky-risk": "read"
      }
    },
    "/v1/company-profile": {
      "get": {
        "operationId": "getCompanyProfile",
        "tags": [
          "Einstellungen"
        ],
        "summary": "Firmenprofil und Firmenwissen",
        "description": "Was der Kunde in dealsky über seine Firma hinterlegt hat und was die KI-Texte der App nutzen: Firmendaten (Einrichtung, Unternehmen) und das Firmenwissen mit Marke, Angebot und Zielgruppe, Ansprache und Tonalität sowie weiteren Notizen (z. B. Schreibstil). Kostet nichts.\n\nDie festen Felder entsprechen den Reitern Brand, Produkt & ICP und Guidelines des Firmenwissens; nicht gepflegte Felder sind null bzw. eine leere Liste. Notizen mit `linkedin_account_id` gelten nur für dieses LinkedIn-Konto und gehen dort dem allgemeinen Eintrag gleichen Namens vor. Höchstens die 300 zuletzt geänderten Einträge, wie in der App.\n\nWie die Einstellungsseiten in der App nur für Inhaber und Admins. Ändern geht nur in der App.\n\n**Berechtigung:** `read:account`\n\n**Recht in dealsky:** nur Leitung (die Person, die den Key erzeugt hat, muss Inhaber oder Admin sein, wie in der App)\n\n**Wirkung:** Liest nur.",
        "responses": {
          "200": {
            "description": "Erfolg",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "examples": [
                        {
                          "company": {
                            "name": "Beispiel GmbH",
                            "website_url": "https://beispiel.de",
                            "logo_url": "https://imagedelivery.net/beispiel/tenants/logo/public"
                          },
                          "brand": {
                            "name": "Beispiel",
                            "description": "Wir bringen mittelständischen Maschinenbauern planbar neue Anfragen über LinkedIn.",
                            "website": "https://beispiel.de",
                            "industry": "B2B-Dienstleistung",
                            "languages": [
                              "Deutsch"
                            ],
                            "competitors": [
                              "Agentur Muster",
                              "Vertriebsprofis AG"
                            ],
                            "colors": [
                              "#FF6B00",
                              "#1A1A1A"
                            ],
                            "logo_url": "https://imagedelivery.net/beispiel/tenants/logo/public"
                          },
                          "product": {
                            "offer": "LinkedIn-Akquise als Komplettpaket: Zielgruppe, Ansprache und Termine in den Kalender des Vertriebs.",
                            "target_audience": "Geschäftsführer und Vertriebsleiter im Maschinenbau, 20 bis 500 Mitarbeitende, DACH",
                            "unique_selling_point": "Persönliche Videos je Lead statt Massennachrichten",
                            "pain_points": "Neukunden kommen nur über Empfehlungen, der Vertrieb hat keine planbaren Termine"
                          },
                          "guidelines": {
                            "salutation": "Sie-Form",
                            "tone": "Sachlich und kurz. Keine Emojis, keine Superlative, kein Fachchinesisch."
                          },
                          "notes": [
                            {
                              "key": "writing_style",
                              "label": "Schreibstil",
                              "category": "stil",
                              "content": "Kurze Sätze, direkte Frage am Ende, per Sie.",
                              "linkedin_account_id": null,
                              "updated_at": "2026-10-12T09:00:00.000Z"
                            },
                            {
                              "key": "acct:7c8d9e0f-1a2b-4c3d-8e4f-5a6b7c8d9e0f:writing_style",
                              "label": "Schreibstil",
                              "category": "stil",
                              "content": "Locker, per Du, mit kurzem Bezug auf den letzten Beitrag.",
                              "linkedin_account_id": "7c8d9e0f-1a2b-4c3d-8e4f-5a6b7c8d9e0f",
                              "updated_at": "2026-10-12T09:00:00.000Z"
                            },
                            {
                              "key": "before_state",
                              "label": "Ist-Zustand",
                              "category": "zielgruppe",
                              "content": "Akquise läuft nur über Messen und Empfehlungen.",
                              "linkedin_account_id": null,
                              "updated_at": "2026-09-30T16:20:00.000Z"
                            }
                          ]
                        }
                      ],
                      "properties": {
                        "company": {
                          "type": "object",
                          "description": "Firmendaten wie unter Einrichtung, Unternehmen",
                          "properties": {
                            "name": {
                              "type": "string",
                              "description": "Firmenname des Kontos"
                            },
                            "website_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Website aus Einrichtung, Unternehmen"
                            },
                            "logo_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Logo aus Einrichtung, Unternehmen (nur http(s)-Adressen)"
                            }
                          },
                          "additionalProperties": false
                        },
                        "brand": {
                          "type": "object",
                          "description": "Marke wie im Reiter Brand des Firmenwissens. Nicht gepflegt: null bzw. leere Liste",
                          "properties": {
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Markenname (Firmenwissen `firmenname`)"
                            },
                            "description": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Beschreibung (Firmenwissen `brand_description`, früher `description`)"
                            },
                            "website": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "URL (Firmenwissen `website`)"
                            },
                            "industry": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Branche (Firmenwissen `branche`)"
                            },
                            "languages": {
                              "type": "array",
                              "description": "Sprache(n) (Firmenwissen `brand_languages`). Liste, in der App als Komma-Liste gepflegt",
                              "items": {
                                "type": "string"
                              }
                            },
                            "competitors": {
                              "type": "array",
                              "description": "Wettbewerber (Firmenwissen `brand_competitors`). Liste, in der App als Komma-Liste gepflegt",
                              "items": {
                                "type": "string"
                              }
                            },
                            "colors": {
                              "type": "array",
                              "description": "Farben (Firmenwissen `brand_colors`). Hex-Farben wie #FF6B00",
                              "items": {
                                "type": "string"
                              }
                            },
                            "logo_url": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Logo (Firmenwissen `brand_logo`, früher `logo`). Nur http(s)-Adressen"
                            }
                          },
                          "additionalProperties": false
                        },
                        "product": {
                          "type": "object",
                          "description": "Angebot und Zielgruppe wie im Reiter Produkt & ICP",
                          "properties": {
                            "offer": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Angebot (Firmenwissen `hauptangebot`, früher `offering`, `angebot_website`)"
                            },
                            "target_audience": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "ICP / Zielgruppe (Firmenwissen `zielgruppe`, früher `audience`)"
                            },
                            "unique_selling_point": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "USP / Alleinstellung (Firmenwissen `unique_mechanism`)"
                            },
                            "pain_points": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Schmerzpunkte (Firmenwissen `pain`, früher `emotional_pain`)"
                            }
                          },
                          "additionalProperties": false
                        },
                        "guidelines": {
                          "type": "object",
                          "description": "Ansprache und Tonalität wie im Reiter Guidelines",
                          "properties": {
                            "salutation": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Ansprache (Firmenwissen `ansprache`)"
                            },
                            "tone": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "Tonalität & Do/Don’ts (Firmenwissen `guidelines`)"
                            }
                          },
                          "additionalProperties": false
                        },
                        "notes": {
                          "type": "array",
                          "description": "Weitere Notizen, neueste zuerst, z. B. Schreibstil, Ist-Zustand, Fallstudie. Leere Einträge und technische Zwischenstände fehlen",
                          "items": {
                            "type": "object",
                            "properties": {
                              "key": {
                                "type": "string",
                                "description": "Schlüssel im Firmenwissen. Beginnt mit acct:<Konto>: bei Einträgen für ein LinkedIn-Konto"
                              },
                              "label": {
                                "type": "string",
                                "description": "Name, wie ihn die App unter „Weitere Notizen“ zeigt"
                              },
                              "category": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Kategorie, z. B. stil, angebot, sonstiges"
                              },
                              "content": {
                                "type": "string",
                                "description": "Inhalt"
                              },
                              "linkedin_account_id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Gilt nur für dieses LinkedIn-Konto (ID wie in /v1/linkedin/accounts) und geht dort dem allgemeinen Eintrag mit gleichem Namen vor. null: gilt für die ganze Firma"
                              },
                              "updated_at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Zeitpunkt der letzten Änderung des Eintrags",
                                "format": "date-time"
                              }
                            },
                            "additionalProperties": false
                          }
                        }
                      },
                      "additionalProperties": false
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "request_id": {
                          "type": "string"
                        },
                        "test_mode": {
                          "type": "boolean",
                          "description": "Nur bei Test-Key: nichts wurde geschrieben"
                        }
                      },
                      "required": [
                        "request_id"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "data",
                    "meta"
                  ]
                },
                "examples": {
                  "beispiel1": {
                    "summary": "Beispiel",
                    "value": {
                      "ok": true,
                      "data": {
                        "company": {
                          "name": "Beispiel GmbH",
                          "website_url": "https://beispiel.de",
                          "logo_url": "https://imagedelivery.net/beispiel/tenants/logo/public"
                        },
                        "brand": {
                          "name": "Beispiel",
                          "description": "Wir bringen mittelständischen Maschinenbauern planbar neue Anfragen über LinkedIn.",
                          "website": "https://beispiel.de",
                          "industry": "B2B-Dienstleistung",
                          "languages": [
                            "Deutsch"
                          ],
                          "competitors": [
                            "Agentur Muster",
                            "Vertriebsprofis AG"
                          ],
                          "colors": [
                            "#FF6B00",
                            "#1A1A1A"
                          ],
                          "logo_url": "https://imagedelivery.net/beispiel/tenants/logo/public"
                        },
                        "product": {
                          "offer": "LinkedIn-Akquise als Komplettpaket: Zielgruppe, Ansprache und Termine in den Kalender des Vertriebs.",
                          "target_audience": "Geschäftsführer und Vertriebsleiter im Maschinenbau, 20 bis 500 Mitarbeitende, DACH",
                          "unique_selling_point": "Persönliche Videos je Lead statt Massennachrichten",
                          "pain_points": "Neukunden kommen nur über Empfehlungen, der Vertrieb hat keine planbaren Termine"
                        },
                        "guidelines": {
                          "salutation": "Sie-Form",
                          "tone": "Sachlich und kurz. Keine Emojis, keine Superlative, kein Fachchinesisch."
                        },
                        "notes": [
                          {
                            "key": "writing_style",
                            "label": "Schreibstil",
                            "category": "stil",
                            "content": "Kurze Sätze, direkte Frage am Ende, per Sie.",
                            "linkedin_account_id": null,
                            "updated_at": "2026-10-12T09:00:00.000Z"
                          },
                          {
                            "key": "acct:7c8d9e0f-1a2b-4c3d-8e4f-5a6b7c8d9e0f:writing_style",
                            "label": "Schreibstil",
                            "category": "stil",
                            "content": "Locker, per Du, mit kurzem Bezug auf den letzten Beitrag.",
                            "linkedin_account_id": "7c8d9e0f-1a2b-4c3d-8e4f-5a6b7c8d9e0f",
                            "updated_at": "2026-10-12T09:00:00.000Z"
                          },
                          {
                            "key": "before_state",
                            "label": "Ist-Zustand",
                            "category": "zielgruppe",
                            "content": "Akquise läuft nur über Messen und Empfehlungen.",
                            "linkedin_account_id": null,
                            "updated_at": "2026-09-30T16:20:00.000Z"
                          }
                        ]
                      },
                      "meta": {
                        "request_id": "req_7f3a…"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/VALIDATION_ERROR"
          },
          "401": {
            "$ref": "#/components/responses/INVALID_API_KEY"
          },
          "402": {
            "$ref": "#/components/responses/PLAN_REQUIRED"
          },
          "403": {
            "$ref": "#/components/responses/SCOPE_MISSING"
          },
          "429": {
            "$ref": "#/components/responses/RATE_LIMITED"
          }
        },
        "x-dealsky-scope": "read:account",
        "x-dealsky-permission": "leitung",
        "x-dealsky-risk": "read"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      },
      "BearerKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Derselbe API-Key als Bearer-Token"
      }
    },
    "responses": {
      "VALIDATION_ERROR": {
        "description": "400: Die Anfrage enthält ungültige Felder. Details stehen in error.details.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "VALIDATION_ERROR",
                "message": "Die Anfrage enthält ungültige Felder. Details stehen in error.details."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "AUTH_REQUIRED": {
        "description": "401: Kein API-Key übergeben. Header X-API-Key oder Authorization: Bearer setzen.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "AUTH_REQUIRED",
                "message": "Kein API-Key übergeben. Header X-API-Key oder Authorization: Bearer setzen."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "INVALID_API_KEY": {
        "description": "401: Der API-Key ist ungültig, abgelaufen oder deaktiviert.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "INVALID_API_KEY",
                "message": "Der API-Key ist ungültig, abgelaufen oder deaktiviert."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "FORBIDDEN": {
        "description": "403: Für diese Aktion fehlt die Berechtigung.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "FORBIDDEN",
                "message": "Für diese Aktion fehlt die Berechtigung."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "SCOPE_MISSING": {
        "description": "403: Dem API-Key fehlt die nötige Berechtigung (Scope).",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "SCOPE_MISSING",
                "message": "Dem API-Key fehlt die nötige Berechtigung (Scope)."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "PLAN_REQUIRED": {
        "description": "402: Die API ist in diesem Tarif nicht enthalten.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "PLAN_REQUIRED",
                "message": "Die API ist in diesem Tarif nicht enthalten."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "NOT_FOUND": {
        "description": "404: Nicht gefunden.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "NOT_FOUND",
                "message": "Nicht gefunden."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "METHOD_NOT_ALLOWED": {
        "description": "405: Diese HTTP-Methode ist für den Endpunkt nicht erlaubt.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "METHOD_NOT_ALLOWED",
                "message": "Diese HTTP-Methode ist für den Endpunkt nicht erlaubt."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "CONFLICT": {
        "description": "409: Der Datensatz existiert bereits oder steht im Konflikt mit einem anderen.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "CONFLICT",
                "message": "Der Datensatz existiert bereits oder steht im Konflikt mit einem anderen."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "BUSINESS_ERROR": {
        "description": "422: Die Aktion ist im aktuellen Zustand nicht möglich.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "BUSINESS_ERROR",
                "message": "Die Aktion ist im aktuellen Zustand nicht möglich."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "RATE_LIMITED": {
        "description": "429: Zu viele Anfragen. Bitte kurz warten und erneut versuchen.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "RATE_LIMITED",
                "message": "Zu viele Anfragen. Bitte kurz warten und erneut versuchen."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "PROVIDER_ERROR": {
        "description": "502: Ein angebundener Dienst hat einen Fehler gemeldet.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "PROVIDER_ERROR",
                "message": "Ein angebundener Dienst hat einen Fehler gemeldet."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "PROVIDER_DISABLED": {
        "description": "503: Ein angebundener Dienst ist gerade nicht verfügbar.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "PROVIDER_DISABLED",
                "message": "Ein angebundener Dienst ist gerade nicht verfügbar."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "PROVIDER_TIMEOUT": {
        "description": "504: Ein angebundener Dienst hat nicht rechtzeitig geantwortet.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "PROVIDER_TIMEOUT",
                "message": "Ein angebundener Dienst hat nicht rechtzeitig geantwortet."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "INTERNAL_ERROR": {
        "description": "500: Ein unerwarteter Fehler ist aufgetreten.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "INTERNAL_ERROR",
                "message": "Ein unerwarteter Fehler ist aufgetreten."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      },
      "MAINTENANCE_MODE": {
        "description": "503: Wartungsarbeiten. Bitte später erneut versuchen.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "ok": {
                  "const": false
                },
                "error": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "VALIDATION_ERROR",
                        "AUTH_REQUIRED",
                        "INVALID_API_KEY",
                        "FORBIDDEN",
                        "SCOPE_MISSING",
                        "PLAN_REQUIRED",
                        "NOT_FOUND",
                        "METHOD_NOT_ALLOWED",
                        "CONFLICT",
                        "BUSINESS_ERROR",
                        "RATE_LIMITED",
                        "PROVIDER_ERROR",
                        "PROVIDER_DISABLED",
                        "PROVIDER_TIMEOUT",
                        "INTERNAL_ERROR",
                        "MAINTENANCE_MODE"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "description": "Bei VALIDATION_ERROR: Liste aus {field, message}"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "meta": {
                  "type": "object",
                  "properties": {
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              },
              "required": [
                "ok",
                "error"
              ]
            },
            "example": {
              "ok": false,
              "error": {
                "code": "MAINTENANCE_MODE",
                "message": "Wartungsarbeiten. Bitte später erneut versuchen."
              },
              "meta": {
                "request_id": "req_7f3a…"
              }
            }
          }
        }
      }
    }
  },
  "x-dealsky-scopes": [
    {
      "scope": "read:leads",
      "description": "Leads, Listen und Lead-Scout-Suchen lesen",
      "sensitive": false
    },
    {
      "scope": "write:leads",
      "description": "Leads und Listen anlegen und ändern",
      "sensitive": false
    },
    {
      "scope": "delete:leads",
      "description": "Leads endgültig löschen",
      "sensitive": true
    },
    {
      "scope": "read:exclusions",
      "description": "Ausschlüsse lesen",
      "sensitive": false
    },
    {
      "scope": "write:exclusions",
      "description": "Ausschlüsse anlegen und entfernen",
      "sensitive": false
    },
    {
      "scope": "read:campaigns",
      "description": "Kampagnen, Schritte, Statistiken und LinkedIn-Dauerläufe lesen",
      "sensitive": false
    },
    {
      "scope": "write:campaigns",
      "description": "Kampagnen anlegen, ändern und Leads zuordnen",
      "sensitive": false
    },
    {
      "scope": "run:campaigns",
      "description": "Kampagnen starten, stoppen und fortsetzen, Leads einschreiben (Außenwirkung)",
      "sensitive": true
    },
    {
      "scope": "read:crm",
      "description": "CRM lesen: Kontakte, Firmen, Deals, Notizen, Aufgaben, Termine",
      "sensitive": false
    },
    {
      "scope": "write:crm",
      "description": "CRM anlegen und ändern",
      "sensitive": false
    },
    {
      "scope": "delete:crm",
      "description": "CRM-Einträge endgültig löschen, z. B. Notizen",
      "sensitive": false
    },
    {
      "scope": "read:inbox",
      "description": "LinkedIn-Postfach lesen",
      "sensitive": false
    },
    {
      "scope": "write:inbox",
      "description": "Postfach pflegen: Status, Schlagwörter, Termin markieren (ohne Senden)",
      "sensitive": false
    },
    {
      "scope": "send:messages",
      "description": "LinkedIn-Nachrichten senden (Außenwirkung)",
      "sensitive": true
    },
    {
      "scope": "read:linkedin",
      "description": "Verbundene LinkedIn-Konten und Limits lesen",
      "sensitive": false
    },
    {
      "scope": "read:analytics",
      "description": "Auswertungen und Kennzahlen lesen",
      "sensitive": false
    },
    {
      "scope": "read:assets",
      "description": "Landingpages, Videos, Medien und Vorlagen lesen",
      "sensitive": false
    },
    {
      "scope": "write:assets",
      "description": "Medien hochladen, Landingpage-Vorlagen anlegen und ändern (ohne Credits)",
      "sensitive": false
    },
    {
      "scope": "generate:assets",
      "description": "Videos, Briefe und Landingpages erzeugen (verbraucht Credits)",
      "sensitive": true
    },
    {
      "scope": "read:webhooks",
      "description": "Webhook-Abos lesen",
      "sensitive": false
    },
    {
      "scope": "write:webhooks",
      "description": "Webhook-Abos anlegen und löschen",
      "sensitive": false
    },
    {
      "scope": "read:team",
      "description": "Team-Mitglieder lesen",
      "sensitive": false
    },
    {
      "scope": "read:account",
      "description": "Mandant, Tarif und Credits lesen",
      "sensitive": false
    }
  ]
}