Meta WhatsApp Cloud API — Architektur

Referenz fuer alle Meta-WhatsApp-Setups (heute Friseur Direct, spaeter potentiell Direct-Meta-Tech-Provider statt 360dialog). Vermeidet Meta-UI-Such-Frust bei jedem Token-Refresh oder neuem Customer.

Hierarchie — was haengt an was

flowchart TB
    PA["Persoenliches Meta-Konto<br/>(dein Login z.B. hello@marvinkuehlmann.com)"]

    BP["Business Portfolio<br/>= Business Manager<br/>= Business Account<br/>(Meta benennt das jaehrlich um)"]

    PA -->|wird Admin| BP

    BP --> APPS["Apps (Developer Apps)<br/>App-ID + App-Secret<br/>+ Webhook-Config"]
    BP --> WABAS["WhatsApp Business Accounts (WABAs)<br/>= 'WhatsApp-Konto'<br/>WABA-ID"]
    BP --> SU["System Users<br/>(fuer API, nicht Mensch)"]
    BP --> PG["Pages + Instagram + Ads<br/>(NICHT relevant fuer WA-Bot)"]

    APPS --> APPCFG["Pro App:<br/>WhatsApp-Tab<br/>+ Webhook-Subscription<br/>+ Permissions"]

    WABAS --> PHONE["Phone Numbers<br/>Phone-Number-ID<br/>+ Display-Name<br/>+ Quality-Rating"]
    WABAS --> TMPL["Templates<br/>(Bestaetigung, Erinnerung)<br/>Approval-pflichtig 1-3 Tage"]

    SU --> TOKEN["Tokens mit Scopes:<br/>whatsapp_business_messaging<br/>whatsapp_business_management"]

    APPS -.-|App muss WABA<br/>subscriben| WABAS
    SU -.-|System User braucht<br/>Asset-Zugriff auf WABA| WABAS
    TOKEN -.-|Token gilt fuer<br/>genau eine App| APPS

Die drei nicht-offensichtlichen Bindings

  1. App ↔ WABA-Subscription: eine App ist nicht automatisch mit einer WABA verbunden. In den WABA-Settings muss die App explizit „assignt” werden. Sonst sieht die App die Phone-Number nicht.
  2. System User ↔ Asset-Zugriff: ein System User sieht nicht automatisch alle WABAs des Portfolios. Entweder Admin (sieht alles) oder Employee mit explizitem Asset-Zugriff pro WABA.
  3. Token ↔ App-Bindung: beim Token-Generieren waehlst du eine App. Der Token wirkt nur fuer Calls die im Namen dieser App gehen. Token von App A funktioniert NICHT fuer App B.

UI-Pfad-Map — Meta verteilt das auf drei Hosts

Was du willstURLKlick-Pfad
App anlegen / managen / Webhook konfigurierenhttps://developers.facebook.com/appsdirekt zur App-Liste
Temporary Token (24h, zum Testen)App-Dashboard → linke Sidebar WhatsApp → API Setup„Temporary access token” oben sichtbar
Phone-Number-ID + WABA-ID nachschauenApp-Dashboard → WhatsApp → API Setup„From” und „To”-Sektionen
Webhook-URL setzen (Inbound-Empfaenger)App-Dashboard → WhatsApp → Configuration„Webhook” Section, Edit → Callback + Verify-Token
Webhook-Felder subscriben (messages, message_status)gleiche Seitenach Verify: Felder haken
Business Portfolio managen / Member einladenhttps://business.facebook.com/settingsDropdown oben links wechselt Portfolio
System Users + Permanent Tokenshttps://business.facebook.com/settingsUsers → System UsersAdd → Admin → Generate Token → App + Scopes + Never
WhatsApp Accounts (WABAs) als Asset verwaltenhttps://business.facebook.com/settingsAccounts → WhatsApp AccountsAsset zu System User assignen geht hier
WhatsApp Manager (Templates + Phone Settings + Insights)https://business.facebook.com/wa/managedirekter Link
Templates einreichenWhatsApp Manager → Message TemplatesCreate Template, Approval 1-3 Tage
Display-Name aendern (Phone)WhatsApp Manager → Phone Numbers → → SettingsDisplay-Name + Re-Verification noetig

Eselsbruecke:

  • developers.facebook.com/apps/<app> = Code-Welt (Webhooks, Temp-Tokens, App-Secrets)
  • business.facebook.com/settings = Verwaltungs-Welt (Users, Permissions, System Users, Asset-Zuordnung)
  • business.facebook.com/wa/manage = WhatsApp-Welt (Templates, Phone-Settings, Insights)

Token-Typen

Token-TypWo erzeugtGueltigWofuer
Temporary Access TokenApp-Dashboard → WhatsApp → API Setup24hSchnelles Testen, NICHT Production
System User Token (Permanent)Business Settings → System Users → Generate Token, Expiration „Never”unbegrenzt (kann revoked werden)Production-Standard
System User Token (60d)Gleicher Pfad, Expiration „60 days”60 TageFallback wenn Permanent nicht erlaubt ist
App Access TokenApp-ID + App-Secret als StringunbegrenztSelten, fuer App-eigene Calls. Nicht fuer WA-Bot relevant.

Wichtig: Permanent-Token kann trotz Expiration „Never” revoked werden bei:

  • Permission-Aenderungen an der App
  • Token-Rotation durch anderen Admin
  • Meta-Policy-Verstoss (Account-Sperre)

Pflicht-Scopes fuer WhatsApp-Bot

  • whatsapp_business_messaging — Senden von Messages
  • whatsapp_business_management — Lesen von Phone-Info, Templates, Webhook-Config

Beide beim Token-Generieren haken. Ohne _management schlagen Tools wie list_templates, get_phone_info, list_phone_numbers fehl.

Webhook-Setup

  1. App-Dashboard → WhatsApp → Configuration → Webhook
  2. Callback URL: https://mcp-whatsapp.agenticventures.de/webhook (oder kundenspezifisch)
  3. Verify Token: muss mit WHATSAPP_WEBHOOK_VERIFY_TOKEN in deinem Secret matchen
  4. Meta sendet GET mit hub.mode=subscribe&hub.verify_token=<token>&hub.challenge=<n> → dein Server muss hub.challenge zurueckschicken bei Token-Match
  5. Subscribe fields: messages (Inbound + Interactive-Reactions) + message_status (sent/delivered/read)

Webhook-Sicherheit: Meta unterschreibt Payload mit HMAC-SHA-256 ueber App-Secret. Header X-Hub-Signature-256: sha256=<hex>. Pflicht-Verify in Production sonst kann jeder POSTs faken. Aktuell in mcp-whatsapp server.py implementiert (seit Audit 2026-05-15 mit META_APP_SECRET-Secret-Key).

Customer-Onboarding-Standardweg (Meta-Direct, ohne 360dialog)

  1. Kunde legt eigenen Meta Business Manager an (oder hat bereits einen)
  2. Kunde invited dich als Admin oder Employee mit Asset-Zugriff auf seine WABA + Phone-Number
  3. Du legst in dem Kunden-Portfolio einen System User an: mcp-whatsapp-<customer-slug>, Role Admin
  4. Du generierst Permanent-Token mit beiden Scopes
  5. Du sourcst die App: entweder eigene Multi-Tenant-App ODER du legst pro Kunde eine eigene App im Kunden-Portfolio an
  6. Du registrierst Webhook bei der App
  7. Du legst neuen Eintrag in receptionist-customers mit phone_number_id, provider=meta-direct, provider_credentials_secret_arn
  8. Du legst Secret an mit JSON {PHONE_NUMBER_ID, BUSINESS_ACCOUNT_ID, ACCESS_TOKEN, WEBHOOK_VERIFY_TOKEN, APP_SECRET}

Schmerz: Schritte 1-2 bei jedem neuen Kunden eine Stunde Setup-Krampf. Genau das was 360dialog Embedded Signup abstrahieren wuerde (1 Klick durch Meta-Login + Permission-Grant).

Wenn Direkt-Tech-Provider-Setup approved: Schritte 1-2 entfallen, Kunde klickt Embedded-Signup-Link → Meta-Popup → fertig. Eigenes Embedded Signup ist Voraussetzung dafuer (siehe Entscheidungs-ADR wenn geschrieben, sonst intern/runs/2026-05-19-aushebel-360dialog/_index.md).

Quirks + Stolperer

  • Token verschwindet nach Generate: der vollstaendige Token wird einmalig angezeigt, nicht spaeter wieder abrufbar. Wenn nicht kopiert: revoken + neu generieren.
  • Token ist App-spezifisch: Permanent-Token von System User wirkt nur fuer Calls im Namen der gewaehlten App. Andere App = neuer Token.
  • Webhook-Verify scheitert ohne Token-Match: wenn der Webhook-Verify-Token im Secret nicht EXAKT mit dem in der App-Configuration matcht: keine Inbound-Webhooks. Mit Apostrophen, Whitespace oder URL-Encoding aufpassen.
  • 24h-Service-Window: Outbound-free-form-Messages nur innerhalb 24h ab letztem User-Inbound. Sonst nur approved Templates. Meta-Error-Code 131047 Re-engagement message.
  • Permanent-Token kann unter Cover revoked werden: Meta hat manchmal Quirks wo „Never expires” trotzdem nach 60 Tagen ablaeuft bei nicht-business-verified Apps. Im Verdacht: Business Verification pruefen.
  • WhatsApp Cloud API hat eigenen rate limit pro Phone-Number-ID — Standard 80 msg/s. Quality-Rating-abhaengiges Skalierung bis 1000 msg/s nach Aging-up. Bei Friseur-Workload kein Issue.

Friseur konkret (Stand 2026-05-19)

KomponenteWert
Business Portfolio„Friseur im Sueden” (vermutlich)
App-ID988192143605811 (Name vermutlich „agentic-friseur-bot”)
App liegt inFriseur-Business-Portfolio
WABA-ID889608426871476
Phone-Number-ID1170948102758111 (= Arnes WhatsApp-Bot-Nummer)
Webhook-URLhttps://mcp-whatsapp.agenticventures.de/webhook
Webhook-Verify-Tokenagentic-friseur-verify-2026 (in Secret)
HMAC-App-Secretin Secret als APP_SECRET-Key (seit Audit 2026-05-15)
Production-Tokenseit 2026-05-18 abend expired, am 2026-05-19 zu rotieren

Token-Rotation-Pfad fuer Friseur: siehe SKILL.