Skip to content
belvoy

For developers

Build voice agents into your own software with the voice agent API

The Belvoy app runs on the same API you get. Managing agents, starting calls and fetching outcomes all work in code too. During the call the agent calls your APIs, and afterwards your system gets a signed webhook. You use your own keys with the AI providers you choose.

The developer documentation goes public soon. Until then, access comes with the pilot.

One API

The app uses the same API you do

There’s no cut-down integration layer in between. A key can do what the app does, within the scopes you give it.

  • REST API

    JSON, an OpenAPI 3.1 spec, cursor pagination and an Idempotency-Key on everything that starts a call. Keys per workspace with their own scopes; test keys behave like live keys but are never billed.

  • Outbound calls and batches

    One call or a whole list. Per call you pass instructions, context, an opening line and the fields you want back. Belvoy handles calling hours, the opt-out list, voicemail detection and retries.

  • Webhooks

    Standard Webhooks, signed with HMAC: conversation.started, conversation.ended, conversation.analyzed, call.failed, batch.completed, task.completed and more. With retries and a delivery log.

  • Tools for the agent

    The agent calls your own HTTP endpoints mid-conversation, with bearer, basic, API key or OAuth2 auth, mTLS and signed requests. Or import operations from your OpenAPI spec.

  • MCP, both ways

    Connect MCP servers as tools for your agent. And Belvoy has an MCP server of its own, so an AI assistant can start, follow and cancel calls.

  • A connector behind your firewall

    For systems that aren’t on the internet. The connector runs in your own network, opens an encrypted connection outwards and only runs the tools you configure. No inbound port needed.

  • Web widget

    One script and one element on your page. The publishable key only works for the agents you choose and from the domains you allow.

  • SDKs

    Typed SDKs for TypeScript and Python, generated from the OpenAPI spec, with helpers for idempotency, pagination and verifying webhooks.

Sample code

From widget to webhook, in real code

No pseudocode: the routes, fields and events come straight from the API. Only the ids and keys are shortened.

The widget on your website

Make the agent public, add your domain and create a publishable key. Then paste this into your page.

<script src="https://app.dev.belvoy.nl/widget.js" async></script>
<belvoy-agent agent-id="agt_01K6…" publishable-key="bv_pub_…" lang="en"></belvoy-agent>

Start an outbound call

A reminder with one question that comes back as data. Thanks to the Idempotency-Key, the same call is never dialled twice.

curl https://app.dev.belvoy.nl/v1/calls/outbound \
  -H "Authorization: Bearer $BELVOY_API_KEY" \
  -H "Idempotency-Key: reminder-4711" \
  -H "Content-Type: application/json" \
  -d '{
    "agentId": "agt_01K6…",
    "phoneNumberId": "pn_01K6…",
    "to": "+31612345678",
    "instructions": "Remind {{customer_name}} of Thursday’s 10:00 appointment and ask whether it is still on.",
    "dynamicVariables": { "customer_name": "Jan" },
    "outcomeFields": [
      { "id": "confirmed", "type": "boolean", "description": "Is the customer coming?" }
    ],
    "metadata": { "appointmentId": "4711" }
  }'

Receive the outcome

After the analysis Belvoy sends conversation.analyzed. Verify the signature on the raw body with the official Standard Webhooks library.

import os
from standardwebhooks import Webhook

wh = Webhook(os.environ["BELVOY_WEBHOOK_SECRET"])  # whsec_…

def handle(raw_body: bytes, headers: dict) -> None:
    event = wh.verify(raw_body, headers)  # checks the signature and timestamp
    if event["type"] == "conversation.analyzed":
        conversation = event["data"]["conversation"]
        print(conversation["id"], conversation["analysis"]["summary"])

A tool call to your own endpoint

An HTTP tool ‘check_availability’ with two arguments. Signed requests let you check that the call really comes from Belvoy.

POST /availability HTTP/1.1
Host: api.example.nl
Content-Type: application/json
webhook-id: msg_…
webhook-timestamp: 1791100800
webhook-signature: v1,…

{"date": "2026-10-10", "party_size": 4}

How it works

From key to outcome

  1. Create an API key

    In the app under Settings → API keys, with only the scopes you need.

  2. Set up an agent

    In the app or through the API, from a template. Connect a number at Telnyx or Twilio.

  3. Let it call

    One at a time, as a batch or through the widget. Each call with its own brief.

  4. Receive the outcome

    Transcript, summary and your own fields arrive by webhook, or you fetch them through the API.

Bring your own keys

Use your own AI and telephony providers

Connect your own accounts and pay the providers directly, at their own rates. Per agent you choose the combination, and you can swap one part without rebuilding the rest.

Speech-to-speech
ElevenLabs AgentsOpenAI RealtimeGemini Live
Speech recognition
DeepgramSonioxElevenLabsOpenAI
Language models
OpenAIAnthropic ClaudeGoogle Gemini
Voices
ElevenLabsCartesiaAzure AI SpeechOpenAI
Telephony
TelnyxTwilio

Tell us what you’re building

Describe what you have in mind and we’ll get in touch about access to the pilot and the API.

Request API access

Prefer email? hello@belvoy.nl