# Provisional Voice API Agents with Telnyx

> Source: <https://github.com/team-telnyx/telnyx-code-examples/tree/main/provisional-telnyx-voice-api-agents-nodejs>
> Published: 2026-06-26 16:05:44+00:00

| name | provisional-telnyx-voice-api-agents | ||
|---|---|---|---|
| title | Provisional Agents with Telnyx Voice API | ||
| description | Start one reusable Telnyx AI Assistant on Telnyx Voice API calls with runtime business instructions selected by the called phone number. | ||
| language | nodejs | ||
| framework | express | ||
| telnyx_products |
|
||
| channel |
|

Start one reusable Telnyx AI Assistant on Telnyx Voice API calls with runtime business instructions selected by the called phone number.

This example shows a Provisional Agents with Telnyx Voice API pattern:

```
base Telnyx AI Assistant + Telnyx Voice API call-time business config = business-specific voice agent
```

The server answers inbound Telnyx Voice API calls, waits for the `call.answered`

webhook, maps the called number to a business config, renders appointment-scheduling instructions, and starts the base Telnyx AI Assistant with a runtime `greeting`

and `instructions`

.

**Answer Call**:`POST /v2/calls/{call_control_id}/actions/answer`

-[API reference](https://developers.telnyx.com/api-reference/call-commands/answer-call)**Start AI Assistant**:`POST /v2/calls/{call_control_id}/actions/ai_assistant_start`

-[API reference](https://developers.telnyx.com/api-reference/call-commands/start-ai-assistant)**Create Call**:`POST /v2/calls`

- optional outbound test helper

```
  caller
    |
    v
  telnyx number
    |
    v
  voice api webhook
    |
    v
  express server
    |
    +--> call.initiated -> answer call
    |
    +--> call.answered
           |
           +--> called number -> examples/number-routing.json
           +--> business config -> prompt template
           +--> ai_assistant_start with runtime instructions and greeting
```

Telnyx is an **AI Communications Infrastructure** platform that combines Voice API call control and AI Assistants on one communications platform. That lets your webhook answer a call, select context from your own application data, and attach an AI voice assistant to the same live call without handing the call across multiple vendors.

Copy `.env.example`

to `.env`

and fill in:

| Variable | Type | Example | Required | Description | Where to get it |
|---|---|---|---|---|---|
`TELNYX_API_KEY` |
`string` |
`KEY_your_telnyx_api_key_here` |
yes |
Telnyx API v2 key used for Voice API commands |
|

`TELNYX_PUBLIC_KEY`

`string`

`base64_public_key`

[Webhook signing docs](https://developers.telnyx.com/docs/api/v2/overview#webhook-signing)`BASE_ASSISTANT_ID`

`string`

`assistant-...`

**yes for live calls**[AI Assistants](https://portal.telnyx.com/#/ai/assistants)`PORT`

`number`

`5000`

`TELNYX_CONNECTION_ID`

`string`

`connection-id`

`npm run call`

[Portal](https://portal.telnyx.com)`TELNYX_FROM_NUMBER`

`string`

`+15551111111`

`npm run call`

[Numbers](https://portal.telnyx.com/numbers/my-numbers)`TEST_TO_NUMBER`

`string`

`+15552222222`

`npm run call`

Prerequisite: Node.js 18 or newer.

```
git clone https://github.com/team-telnyx/telnyx-code-examples.git
cd telnyx-code-examples/provisional-telnyx-voice-api-agents-nodejs
cp .env.example .env
npm install
```

Create a generic Telnyx AI Assistant for appointment scheduling. Keep it business-agnostic: model, voice, tools, and stable behavior belong on the base assistant. Clinic names, hours, services, and greetings come from runtime config in this example.

Set the base assistant id in `.env`

:

```
BASE_ASSISTANT_ID=assistant-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

Preview the generated Telnyx Voice API `ai_assistant_start`

payload without making a call:

```
npm run preview -- smile-dental
```

Try another config:

```
npm run preview -- northside-medical
```

Start the server:

```
npm start
```

Expose it publicly:

```
ngrok http 5000
```

Configure your Telnyx Voice API application webhook URL:

```
https://<id>.ngrok.io/webhooks/voice
```

Assign your Telnyx number to that Voice API application, then map the number in `examples/number-routing.json`

:

```
{
  "+15551111111": "smile-dental"
}
```

Call the mapped number. The expected flow is:

- Telnyx sends
`call.initiated`

. - The server answers the call.
- Telnyx sends
`call.answered`

. - The server maps the called number to a business config.
- The server starts the base Telnyx AI Assistant with runtime instructions and greeting.

Telnyx Voice API outbound testing is useful when you want to force a business config using `client_state`

instead of number routing:

```
npm run call -- smile-dental
```

The Telnyx Voice API outbound helper places a call and encodes:

```
{ "business_config": "smile-dental" }
```

When the Telnyx Voice API call is answered, the webhook reads that `client_state`

first. If there is no usable `client_state`

, it falls back to called-number routing.

Receives Telnyx Voice API webhooks. Telnyx calls this endpoint directly.

For local testing without Telnyx signatures, leave `TELNYX_PUBLIC_KEY`

unset. For production, set `TELNYX_PUBLIC_KEY`

so the server verifies webhook signatures.

```
curl http://localhost:5000/health
```

Response:

```
{
  "status": "ok",
  "webhook": "/webhooks/voice",
  "configs": ["smile-dental", "northside-medical", "brightcare-physical-therapy"]
}
```

| Issue | Cause | Fix |
|---|---|---|
Webhook returns `401 invalid signature` |
`TELNYX_PUBLIC_KEY` is set but the request is not signed by Telnyx |
Use a real Telnyx webhook, or unset `TELNYX_PUBLIC_KEY` for local curl testing |
Live call returns `BASE_ASSISTANT_ID is required` |
No base assistant id is configured | Create a generic AI Assistant and set `BASE_ASSISTANT_ID` |
| No business config is selected | The called number is not in `examples/number-routing.json` |
Add the called number in E.164 format |
| Call rings forever | Telnyx is not reaching your webhook or the call was not answered | Check the ngrok URL, Voice API application webhook URL, and number assignment |
`ai_assistant_start` fails |
The call is not answered, assistant id is invalid, or the API key lacks permissions | Confirm `call.answered` arrived, check `BASE_ASSISTANT_ID` , and verify the API key |

[build-voice-ai-agent-nodejs](https://raw.githubusercontent.com/team-telnyx/telnyx-code-examples/main/build-voice-ai-agent-nodejs/README.md)- Build a voice AI agent with Telnyx Inference and Call Control[route-phone-calls-to-ai-agent-nodejs](https://raw.githubusercontent.com/team-telnyx/telnyx-code-examples/main/route-phone-calls-to-ai-agent-nodejs/README.md)- Receive and answer inbound Voice API calls[create-ai-assistant-nodejs](https://raw.githubusercontent.com/team-telnyx/telnyx-code-examples/main/create-ai-assistant-nodejs/README.md)- Create a reusable AI Assistant
