Create an OpenAI Realtime Voice Agent

Introduction

The openaivoiceagent.cs sample connects an inbound 3CX call to an OpenAI Realtime voice session. It can greet callers, answer general questions, search the permitted 3CX directory entries, connect callers, offer voicemail or chat, and save useful caller context when that feature is enabled.

The script also includes a disabled get_department_hours custom tool that demonstrates how to register a safe AI-callable function.

This script requires a 3CX AI Edition license, a PBX build Update 10, and an OpenAI API account.

Create the Call Script in 3CX

  • Sign in to the 3CX Admin Console.
  • Go to Admin > Integrations > Call Scripts.
  • Select +Add from Store.

  • Choose openaivoiceagent.cs.

  • Enter a lowercase script name without spaces, for example openaireception.
  • Select how the script will run; for a receptionist, assign a dedicated DID or route the appropriate inbound trunk calls to the script.
  • Select the department that owns the script.
  • Confirm the selection to open the code editor.

Configure OpenAI and the Script

Add the following parameters to the PBX:

  • OPENAI_API_KEY - the API key for your OpenAI project.
  • OPENAI_REALTIME_MODEL - the OpenAI Realtime model.

Leave ApiKeyOverride and ModelOverride empty in the script. When these values are empty, the script automatically reads the API key and model from the PBX parameters.

Do not enter the OpenAI API key directly in the script, especially if the script will be shared, exported or published. A value configured in ApiKeyOverride or ModelOverride takes precedence over the corresponding PBX parameter.

Next, review these customer settings near the top of openaivoiceagent.cs:

Setting

Purpose

Sample value

FallbackDestination

Route used when media or the AI session fails

102

VoiceName

OpenAI voice used by the agent

Coral

AgentName

Name presented to the provider session

Alex

AllowAllVisibilityForTesting

Exposes all supported directory objects

true

VisibleNumbers

Approved extensions, queues, or ring groups

100, 102

VisibleDepartments

Departments the AI may search

Sales, Support

VisibleRoles

Optional permitted roles

empty

AgentInstructions

Company identity, behavior, and routing rules

Example Company

AddAll() is convenient for an initial test but should normally be disabled before production. Set AllowAllVisibilityForTesting to false, then configure only the numbers, departments, and roles the agent needs.

To enable the sample custom tool, review its static response and uncomment:

RegisterExampleCustomTool();

Replace the example with a trusted data source before using it for real customer information.

Select Save to compile. Confirm that the Script output reports a successful compilation before assigning production traffic.

How It Works

  • An inbound call reaches the script route point.
  • The script clears and rebuilds the AI directory visibility list.
  • 3CX prepares the media channel.
  • The script starts an OpenAI Realtime voice session.
  • The agent uses only the built-in 3CX functions and any explicitly registered custom tools.
  • A successful transfer hands the caller to the selected 3CX destination.
  • If media setup or the provider session fails, the script attempts the configured fallback and then plays the ERROR prompt if routing also fails.

Test the Script

  • Call the assigned DID and confirm the greeting and selected voice.
  • Search for an allowed extension by name and number.
  • Confirm that hidden extensions cannot be searched or selected.
  • Test an ambiguous directory match.
  • Test transfer, unavailable-user voicemail, and chat-message behavior.
  • Use an invalid provider key in a test environment and verify fallback routing.
  • End the conversation naturally and confirm session cleanup.

Troubleshooting

  • Provider session fails: Verify OPENAI_API_KEY, the supported realtime model, network access, licensing, and the target PBX build.
  • The agent cannot find a user: Check AllowAllVisibilityForTesting, VisibleNumbers, VisibleDepartments, and VisibleRoles.
  • The wrong objects are visible: Call Clear() before adding the production visibility list and avoid AddAll().
  • Fallback does not work: Confirm the destination exists and can be reached from the assigned department.
  • No error prompt is heard: Confirm ERROR exists in the active prompt set.

See Also

Last Updated

This guide was last updated on 9 September 2026

https://www.3cx.com/docs/open-ai-voice-agent/