Live-Erkenntnisse 2026-05-13
sipgate basic / team „SIP-Konto” ist NICHT LiveKit-trunk-tauglich. Sipgates SIP-Konten im basic/team-Tarif sind klassische Endgeraet-Accounts (Client REGISTERed sich, sipgate INVITEt das Geraet bei Anruf). LiveKit Cloud Inbound erwartet hingegen das Trunk-Pattern (INVITE landet direkt am LiveKit-FQDN, kein REGISTER-Hop). Resultat: SIP-Konto-Credentials in den LiveKit-Inbound-Trunk zu legen schlaegt fehl — LiveKit kann sich nicht bei sipgate registrieren, und sipgate schickt ohne registrierten Client keine Calls an LiveKit. Befund verifiziert beim Versuch, Marvins bestehende sipgate-Nummern (0251er + 01579er) anzubinden.
Pfade die sipgate-basic-tauglich machen wuerden:
- sipgate trunking 2.0 dazubuchen (eigener Tarif, paar Tage KYC, ~9.95 EUR/Mo plus neue Geo-Nummer; bestehende Nummer portierbar BNetzA 2-4 Wochen)
- Eigene SIP-Proxy hosten (Asterisk/FreeSWITCH in Docker), die bei sipgate REGISTERed und INVITEs an LiveKit forwarded — 1-2 Tage Engineering, aber DSGVO-clean
Pragmatische Alternative fuer POC: Telnyx. API-first, vollautomatisch von Claude aus konfigurierbar (Account-Sign-up + Funding bleibt manuell), US-Nummern 1 upfront + $1/Mo. Konkretes Setup siehe Abschnitt „Schritt-fuer-Schritt mit Telnyx (verifiziert 2026-05-13)” unten.
Twilio-Account-Recovery: Marvins bestehender Twilio-Account haengt an einer alten Handynummer ohne Recovery-Code. Recovery via Support-Ticket dauert Stunden bis Tage. Fuer heute-Abend-Pfade blockt das den Twilio-Weg.
Phone-Anbindung — SIP-Trunk fuer den LiveKit-Worker
Vom Browser-POC zu „ruf hier an und sprich mit dem Bot”. Der bestehende Worker (agent.py) muss nicht angefasst werden — LiveKit Cloud uebernimmt Sample-Rate-Conversion (SIP 8 kHz ↔ Worker 48 kHz). Wir brauchen nur drei Dinge:
- DE-Nummer + SIP-Trunk bei einem Telco-Provider
- Inbound Trunk in LiveKit registrieren (Provider-IPs + Auth)
- Dispatch Rule die eingehende Calls auf einen Room routet — der Worker matched dort genauso wie heute beim Browser-Call
Vendor-Optionen fuer die Nummer
| Twilio Elastic SIP Trunking | Telnyx SIP Trunking | sipgate Trunking Basic | |
|---|---|---|---|
| DE-Geo-Nummer/Monat | ~$1.15 | ~$1.00 | ab 9.95 EUR (Paket) |
| Eingehende Min | $0.022 | $0.008 | inklusiv |
| Auth | IP-Whitelist + Digest | IP-Whitelist + Digest | Digest |
| LiveKit-Doku | offiziell verifiziert | offiziell verifiziert | nicht offiziell, generisch SIP |
| DPA / AVV | Standard-DPA (US, EU-SCC) | DPA + EU-Region-Routing | DPA, Hosting DE |
| Free-Tier | $15 Trial-Credit | $2 Trial-Credit | nein |
| Onboarding | Selfservice, sofort live | Selfservice + KYC Email-Bestaetigung | Vertrag + KYC, paar Tage |
Empfehlung:
- Twilio fuer den ersten POC-Anruf — $15 Trial reicht fuer 600+ Min Test, beste LiveKit-Doku, in 30 Min live. Pragmatisch wenn wir morgen mit Aylem-Inhaber demoen wollen.
- sipgate fuer Aylem-Live-Betrieb — wenn der Bot beim Restaurant fest am Hauptanschluss haengt, ist DE-Hosting + EUR-Tarif + voll-DSGVO sauberer. Wechsel ist 5-Minuten-Konfig-Aenderung auf der LiveKit-Seite, kein Code-Change.
Telnyx ist die Mitte — guenstiger pro Minute als Twilio, EU-Routing, aber kein DE-Hosting.
Schritt-fuer-Schritt mit Twilio (Trial-Setup)
1. Twilio-Account + DE-Nummer
- Anmelden: https://www.twilio.com/try-twilio (Trial = $15 Credit)
- Console: https://console.twilio.com
- Nummer kaufen: Console → Phone Numbers → Buy a Number → Country = Germany, Capabilities = Voice. Lokale Vorwahl waehlen (z.B. 02381 fuer Hamm gibt es selten in Twilio, sonst 030/Berlin oder eine DE-Mobilnummer mit +49 15).
- Notiere die Nummer im E.164-Format, z.B.
+4915123456789.
2. SIP-Trunk bei Twilio anlegen
- Console → Elastic SIP Trunking → Trunks → Create Trunk
- Friendly Name:
aylem-livekit - Sektion Termination (egal fuer reines Inbound — leer lassen)
- Sektion Origination → Add Origination URI:
- URI:
sip:<dein-livekit-domain>.sip.livekit.cloud(LiveKit Cloud zeigt die SIP-URI an unter Project Settings → SIP) - Priority 10, Weight 10, Enabled
- URI:
- Sektion Numbers → Add Existing → die gekaufte Nummer assignen
- Sektion Authentication:
- Option A (einfach): Acl = LiveKit-Cloud-IPs erlauben (LiveKit-Doku listet die Inbound-Source-IPs unter https://docs.livekit.io/sip/cloud-provider/)
- Option B (sicherer): Credentials = Digest-User+Passwort generieren, in LiveKit-Trunk hinterlegen
- Save
3. Inbound Trunk in LiveKit anlegen
LiveKit Cloud Console oeffnen: https://cloud.livekit.io → Project waehlen → SIP → Inbound Trunks → Create Trunk
Oder per CLI (sauberer fuer Doku):
# lk = livekit-cli, install via: brew install livekit/tap/livekit-cli
lk sip inbound create --request - <<'JSON'
{
"trunk": {
"name": "twilio-aylem",
"numbers": ["+4915123456789"],
"auth_username": "livekit",
"auth_password": "<digest-password-aus-twilio>"
}
}
JSONAntwort enthaelt sip_trunk_id (Format ST_xxx). Notieren.
4. Dispatch Rule fuer den Worker
lk sip dispatch create --request - <<'JSON'
{
"trunk_ids": ["ST_xxx"],
"rule": {
"dispatch_rule_individual": {
"room_prefix": "aylem-phone-"
}
},
"hide_phone_number": false
}
JSONdispatch_rule_individual legt pro Anruf einen Room mit Prefix aylem-phone-
an — Worker matched automatisch, weil er auf alle Rooms im Project hoert
(default agent dispatch). Wenn wir Multi-Tenant brauchen, koennen wir spaeter
verschiedene Dispatch-Rules pro Trunk anlegen.
5. Test-Anruf
- Worker lokal laufen lassen:
python agent.py dev(wie bisher) - Beliebiges Handy →
+4915123456789anrufen - Erwartung: Tuet → Greeting der Aylem-Voice innerhalb 1-2s → freier Dialog
Twilio-Console hat unter Monitor → Logs → Voice eine Liste der Anrufe inkl. SIP-Status — wenn was nicht klappt, zeigt das den Failure-Reason.
Latenz-Erwartung
Beim Phone-Pfad addiert sich die PSTN-Latenz (~50-150 ms vom Handy bis Twilio) oben drauf. Der heutige Browser-E2E von 1-1.5s sollte aufs Phone ~1.5-2s werden. Wenn das im Test laenger als 3s wird:
min_endpointing_delayin agent.py erhoehen (0.2 → 0.4) — verhindert dass der Worker schon antwortet waehrend der Anrufer noch nachdenkt- Bedrock-Region im SDK pruefen —
eu-central-1ist richtig fuer Hamm-Calls; bei Provider-Hops auch sicher dass der LiveKit-Cloud-Endpoint EU ist - Cartesia
voice_engineggf. aufphone-Profile umstellen (Sonic 2 hat eine separate Phone-optimierte Inferenz)
Wenn du auf sipgate wechseln willst
Nach Twilio-Demo, fuer den Aylem-Live-Betrieb:
- sipgate Trunking-Account: https://app.sipgatebasic.de → Tarif „sipgate trunking basic” buchen (9.95 EUR/Mo, inkl. eine Geo-DE-Nummer)
- Im sipgate Webclient: Telefonanlage → SIP-Konten → Neu → Auth-Username + Passwort generieren
- sipgate SIP-Server =
sipconnect.sipgate.de - In Twilio: Trunk pausieren (oder Nummer rausnehmen)
- In LiveKit: einen neuen Inbound Trunk mit den sipgate-Credentials anlegen,
Dispatch Rule auf die neue Trunk-ID umschwenken (oder beide Trunks im
trunk_ids-Array lassen — dann gehen Anrufe von beiden Nummern an den gleichen Worker) - Nummer portieren (optional, dauert 2-4 Wochen bei der BNetzA-Mitschleppe) oder neue Nummer claimen
Kosten-Schaetzung Aylem-Live (sipgate, 30 Min/Tag)
| Posten | Monat |
|---|---|
| sipgate trunking basic + 1 Nummer | 9.95 EUR |
| LiveKit Cloud (30 Min/Tag = 900 Min/Mo, Free-Tier deckt 10k Min) | 0 EUR |
| Deepgram nova-3 (900 Min × $0.0043/Min) | ~$4 |
| Bedrock Claude Haiku 4.5 EU (~20 Turns/Call × 30 Calls/Tag = ~600 Turns/Tag × 30 = 18k Turns/Mo × ~$0.0003) | ~$5 |
| Cartesia Sonic 2 (900 Min × $0.025/Min nach Free-Credit) | ~$22 |
| Summe | ~30 EUR (zzgl. Gespraechsminuten ab Trunk-Tarif) |
Bei hoeherem Volumen: Cartesia ist der teuerste Posten und der einzige der linear mit Anrufdauer skaliert. Alternative-TTS-Optionen siehe ADR llm-hosting-eu-optionen (falls dort schon aufgeschrieben — sonst beim Vendor-Wechsel ergaenzen).
Open Loops nach diesem Setup
- Outbound-Calls (Bot ruft an, z.B. Bestaetigungs-Call beim Restaurant nach Reservierung) — LiveKit kann das auch, anderer SIP-Trunk-Modus
- Call-Recording fuer Eval (DSGVO §9 — Anrufer-Ansage am Anfang Pflicht)
- Number-Pool fuer Multi-Tenant — pro Kunde eigene Nummer, gleicher Worker
- AWS-Hosting des Workers (Fargate eu-central-1) statt Mac in Hamm — die Hop-Latenz vom heimischen DSL ist ein realer Faktor
Schritt-fuer-Schritt mit Telnyx (verifiziert 2026-05-13)
Live durchgefuehrt — Setup steht im Vault unter
.env.local. Credentials NICHT
committen, sind dort lokal mit TELNYX_*-Praefix abgelegt.
1. Telnyx-Account + API-Key (manuell)
- Sign-up: https://telnyx.com/sign-up — Google-OAuth funktioniert (kein Email-Verify-Hop)
- API Keys: https://portal.telnyx.com → API Keys → Create API Key V2
- Funding: https://portal.telnyx.com/#/app/billing/payments → mindestens 0 upfront/monthly, aber inbound-Minuten ($0.008/Min) ziehen aus Saldo. Trial-Account hat oft eine kleine Grace.
2. FQDN-Connection anlegen (oder bestehende umkonfigurieren)
Trial erlaubt nur eine FQDN-Connection pro Account — beim Sign-up wird typisch schon eine „TEST”-Connection angelegt. Wir nehmen die wieder.
# Existing Connections listen
curl -s -H "Authorization: Bearer $TELNYX_API_KEY" \
https://api.telnyx.com/v2/connections | jq
# Connection auf TCP + LiveKit-tauglich umbenennen
curl -X PATCH -H "Authorization: Bearer $TELNYX_API_KEY" \
-H "Content-Type: application/json" \
"https://api.telnyx.com/v2/fqdn_connections/$TELNYX_FQDN_CONNECTION_ID" \
-d '{"connection_name":"aylem-livekit","transport_protocol":"TCP","active":true}'3. LiveKit-FQDN dazuhaengen
curl -X POST -H "Authorization: Bearer $TELNYX_API_KEY" \
-H "Content-Type: application/json" \
https://api.telnyx.com/v2/fqdns \
-d '{
"connection_id":"'$TELNYX_FQDN_CONNECTION_ID'",
"fqdn":"<dein-livekit-subdomain>.sip.livekit.cloud",
"port":5060,
"dns_record_type":"a"
}'LiveKit-Subdomain steht im Cloud-Dashboard unter Project Settings → SIP
(z.B. test-t1lmm63r.sip.livekit.cloud).
4. Nummer kaufen oder bestehende assignen
# Verfuegbare Nummern listen
curl -s -H "Authorization: Bearer $TELNYX_API_KEY" \
"https://api.telnyx.com/v2/available_phone_numbers?filter%5Bcountry_code%5D=DE&filter%5Blimit%5D=10" | jq
# Nummer kaufen (Trial-Limit: 1 number_order — bei Sign-up wird oft schon
# eine zugewiesen, dann nur ASSIGNen statt kaufen)
curl -X POST -H "Authorization: Bearer $TELNYX_API_KEY" \
-H "Content-Type: application/json" \
https://api.telnyx.com/v2/number_orders \
-d '{"phone_numbers":[{"phone_number":"+49209..."}],
"connection_id":"'$TELNYX_FQDN_CONNECTION_ID'"}'
# Bestehende Nummer dem Trunk assignen (wenn schon im Account)
curl -X PATCH -H "Authorization: Bearer $TELNYX_API_KEY" \
-H "Content-Type: application/json" \
"https://api.telnyx.com/v2/phone_numbers/$NUMBER_ID" \
-d '{"connection_id":"'$TELNYX_FQDN_CONNECTION_ID'"}'5. LiveKit-Seite (analog Twilio)
cd intern/projekte/telefon-assistent-aws/livekit-agent && set -a && source .env.local && set +a
# Inbound Trunk mit der Telnyx-Nummer
lk sip inbound create --name "telnyx-aylem" --numbers "+49209..."
# returnt SIPTrunkID ST_xxx
# Dispatch Rule fuer Worker-Routing
lk sip dispatch create --name "aylem-phone-dispatch" \
--trunks "ST_xxx" --individual "aylem-phone-"6. Worker starten + Test
.venv/bin/python agent.py dev > /tmp/livekit-worker.log 2>&1 &
# warten bis "registered worker region: ..." im LogAnrufen, Bot meldet sich. Bei Live-Test 2026-05-13 wurde Setup-Schritte 1-5 erfolgreich verifiziert, der finale Test-Anruf wurde aus Kostengruenden verschoben (US-Nummer +1 838 206 8690 → Anruf aus DE bedeutet Mobilfunk-Auslandsgebuehr ~30 Cent/Min beim Mobilfunkanbieter).
Auth-Modell-Hinweis
LiveKit Inbound Trunks haben Felder auth_username + auth_password —
aber nur fuer den umgekehrten Fall (Provider authentifiziert sich bei
LiveKit). Bei Telnyx-FQDN-Connections wird per FQDN-Routing direkt
geINVITEt, keine Auth-Credentials noetig. Fuer Production-Hardening:
allowed_addresses mit Telnyx-Source-IPs auf dem LiveKit-Trunk
hinterlegen (verhindert dass beliebige IPs Calls auf die Nummer
schicken).
Open Loops nach diesem Setup
- Outbound-Calls (Bot ruft an, z.B. Bestaetigungs-Call beim Restaurant nach Reservierung) — LiveKit kann das auch, anderer SIP-Trunk-Modus
- Call-Recording fuer Eval (DSGVO §9 — Anrufer-Ansage am Anfang Pflicht)
- Number-Pool fuer Multi-Tenant — pro Kunde eigene Nummer, gleicher Worker
- AWS-Hosting des Workers (Fargate eu-central-1) statt Mac in Hamm — die Hop-Latenz vom heimischen DSL ist ein realer Faktor
- DE-Nummer bei Telnyx kaufen (2 Setup + $1/Mo) — heute fehlte das Funding fuer Marvin DE-tauglich, US-Nummer war kostenlos aber Anrufkosten am Handy hoch
allowed_addressesauf LiveKit-Trunk mit Telnyx-Source-IPs (Security-Hardening)
Cross-Refs
- Worker-Code: agent.py
- MCP-Tools: server.py
- Projekt-Plan: _index.md
- LiveKit SIP Docs: https://docs.livekit.io/sip/
- LiveKit SIP CLI:
lk sip --help - Telnyx Number-Search-API: https://developers.telnyx.com/api/numbers/list-available-phone-numbers
- Telnyx FQDN-Connection-API: https://developers.telnyx.com/api/connections/list-fqdn-connections