Bring Your Own Model (BYOM)
Bring Your Own Model (BYOM)
What you build: an agent whose “brain” is your server. Voicebip answers the call, transcribes the caller, and POSTs each turn to your signed webhook_url. You run whatever model you like (OpenAI, Claude, a fine-tune, a rules engine), return the reply text, and Voicebip speaks it. You own the prompt and the model; Voicebip owns the phone line.
Who it’s for: teams with an existing LLM stack, strict data-residency needs, or a proprietary model they can’t hand over. Also the escape hatch when hosted-AI features don’t fit.
BYOM is a signed relay — no Voicebip model runs. Because your endpoint is the model, the dashboard’s system_prompt and tool_definitions fields do not apply to BYOM agents — your prompt and tools live in your own code. If you want Voicebip to run the model and call your functions instead, that’s Tool-calling, a different (hosted) path.
Prerequisites
- An HTTPS
webhook_urlthat responds within 5 seconds (the hard timeout — slower responses are treated as failures and count against the circuit breaker). - Your workspace signing secret (dashboard → Workspace → Signing Secret) — BYOM requests are HMAC-signed and you must verify them.
Step 1 — Create a BYOM agent
Set ai_provider: "byom" and point webhook_url at your endpoint:
Step 2 — Handle the turn request
Each caller turn arrives as a signed POST with a BYOMVoiceWebhookRequest body. Verify (X-Voicebip-Signature = HMAC-SHA256 of "{timestamp}.{raw_body}", timestamp within ±300 s), run your model, return { "text": ... }:
The inbound BYOMVoiceWebhookRequest:
Your response is a BYOMVoiceWebhookResponse. Only text is required; end_call, transfer_to, and dtmf are mutually exclusive with a normal reply:
Step 3 — Inbound screening (optional)
If the agent has screening_enabled, Voicebip fires one pre-greeting request with event: "call.screening" (empty messages, no transcription). Reply { "end_call": true } to reject the caller (optionally with text spoken before hangup) or { "end_call": false } to allow (optionally with text as a dynamic greeting override). On error/timeout, the agent’s screening_fail_closed policy decides.
Step 4 — Add RAG yourself (optional)
BYOM doesn’t auto-retrieve. Query a knowledge base and inject the chunks into your prompt before calling your model:
Messaging BYOM
The same pattern covers WhatsApp/SMS: inbound messages arrive as a BYOMMessagingWebhookRequest ({agent_id, conversation_id, channel, from_number, to_number, inbound_message, history, metadata}) at the same webhook_url, and you return the reply. See WhatsApp AI agent.
Fail-closed signing
BYOM requests are signed, and Voicebip refuses to send unsigned — if your signing secret can’t be resolved, the request is dropped, not sent in the clear (tracked via voicebip_byom_signing_errors_total). On your side, verify every request and reject mismatches. Secret rotation moves the old secret to a 24-hour grace window (signing_secret_previous), so accept either the current or previous secret during rotation. Rotate via POST /v1/workspace/signing-secret/rotate (the plaintext is shown once).
Other stacks
Reference handlers for Flask, Go, and Next.js, plus Claude and OpenAI integrations, live in Code Examples — the same verify → model → reply shape.
Test it
BYOM turns are dispatched to your webhook_url during a live call, so they aren’t part of POST /v1/webhooks/test (which covers call.* / message.* lifecycle events). Test by POSTing a sample BYOMVoiceWebhookRequest (above) to your own endpoint with a valid signature, then place a real call in the sandbox to see it end-to-end.
Troubleshooting
Next steps
- Prefer Voicebip to run the model and call your functions? → Tool-calling.
- Add retrieval to your prompt → Knowledge Base deep-dive.
- Per-language handling and latency tips → Best Practices.