Keep Vapi BYO-SIP-trunks alive on flaky carriers. Detects silent SIP registration drops and rotates credentials automatically — no manual intervention, no missed calls.
Built from the production watchdog running on Julia, the AI phone agent at +49 2562 187 99 13.
Vapi's BYO SIP integration sometimes loses registration on certain carriers (easybell, sipgate, Telekom CompanyFlex) without notification. Symptoms:
- Inbound calls fail with SIP 503/404 even though the Vapi dashboard says "healthy"
- The trunk shows
registered: truein the API for hours after it actually died - A 30-minute call window goes by before anyone notices
The root cause is usually a stuck byo-sip-trunk credential object on Vapi's side. Vapi's recommended fix is to delete and recreate the credential — which you don't want to do manually at 3 AM.
A systemd timer runs every 30 minutes and:
- Pings the trunk via Vapi's diagnostic API
- If the trunk has been unhealthy for
>= 3checks in a row, performs a hard reset:- Creates a fresh
byo-sip-trunkcredential with the same SIP params - Patches the affected phone number to point at the new credential
- Deletes the old (broken) credential
- Creates a fresh
- Sends a notification mail with the rotation details
- Logs everything to
/var/log/vapi-watchdog.log
Average rotation time: 8 seconds. Average missed-call window before rotation: <30 min.
git clone https://github.com/netzhandwerker/vapi-byo-sip-watchdog.git
cd vapi-byo-sip-watchdog
sudo ./install.shThen edit /etc/vapi-watchdog/config.env:
VAPI_API_KEY=... # private API key (NOT the public key)
VAPI_PHONE_NUMBER_ID=... # the phone number to monitor
VAPI_ASSISTANT_ID=... # the assistant attached to this number
SIP_GATEWAY=sip.your-carrier.tld
SIP_USERNAME=...
SIP_PASSWORD=...
ALERT_EMAIL=ops@example.com # optional, leave blank to disable
FAIL_THRESHOLD=3 # consecutive failures before rotatingEnable the timer:
sudo systemctl enable --now vapi-watchdog.timer
systemctl list-timers vapi-watchdog.timer ┌───────────────────────┐
│ Check trunk health │ every 30 min
└──────────┬────────────┘
│
┌──────────────┴──────────────┐
│ │
Healthy? 3× failed?
│ │
Reset count Hard reset:
│ │
│ 1) POST /credential
│ (new byo-sip-trunk)
│ 2) PATCH /phone-number
│ (point at new cred)
│ 3) DELETE /credential
│ (old, broken cred)
│ 4) Mail notification
▼ ▼
Done Done
The rotation is atomic from the caller's perspective: existing in-flight calls finish on the old credential, new calls hit the new credential. There is no service interruption.
| Variable | Required | Default | Purpose |
|---|---|---|---|
VAPI_API_KEY |
yes | — | Vapi private API key |
VAPI_PHONE_NUMBER_ID |
yes | — | UUID of the phone number to monitor |
VAPI_ASSISTANT_ID |
yes | — | UUID of the assistant attached |
SIP_GATEWAY |
yes | — | Carrier SIP gateway hostname |
SIP_USERNAME |
yes | — | SIP auth username |
SIP_PASSWORD |
yes | — | SIP auth password |
ALERT_EMAIL |
no | (none) | If set, notify on rotation |
SMTP_HOST |
no | localhost |
For sending alert mails |
SMTP_PORT |
no | 25 |
SMTP port |
FAIL_THRESHOLD |
no | 3 |
Consecutive failures before rotation |
CHECK_INTERVAL |
no | 30min |
systemd OnCalendar expression |
If you operate a 24/7 Vapi-based phone agent and your carrier isn't on Vapi's preferred list (Twilio, Telnyx, Vonage), you've hit this problem. We did, while running Julia, our AI receptionist on the German carrier easybell. After three weekends of manually re-creating credentials, we wrote this.
- Not a replacement for monitoring (use Vapi's own alerts in parallel)
- Not multi-trunk: one watchdog per phone number
- Not magic: if Vapi's whole API is down, you still get missed calls
MIT. Adapt freely.
Built by Daniel Wesseling at Die Netzhandwerker.