I believe it should be mention that we do have a solution that gives you the flexibility to use any OpenAI (or other provider) endpoint, even if not as simple as the build in voice agents in its setup:
https://www.3cx.com/blog/docs/programmable-extensions-ai-providers/
https://www.3cx.com/docs/agentic-call-control-ai-providers/
https://github.com/3cx/agentic-call-control
And an AI generated guide on how to set the relevant endpoint:
To invoke EU-specific endpoints for GDPR and data residency compliance within the 3cx/agentic-
call-control repository (specifically the examples/openai-realtime Programmable Extension), you
need to configure the underlying OpenAI / WebSockets client to point to OpenAI's European endpoint
([https://eu.api.openai.com](https://eu.api.openai.com) / wss://eu.api.openai.com) or
an OpenAI-compatible EU proxy/gateway.
Because agentic-call-control uses an SDK (such as openai Node.js client or raw WebSockets for real-
time WebRTC/audio sessions), the default target is api.openai.com.
Step 1: Update the Node.js OpenAI Client Base URL
If your Programmable Extension uses the official OpenAI Node.js SDK or standard REST call initializations, you
must override the baseURL parameter:
1. Open the initialization file (typically found in examples/openai-realtime/src/ or index.ts).
2. Locate where the OpenAI client is instantiated (e.g., new OpenAI(...)).
3. Set the baseURL parameter to the EU endpoint:
import OpenAI from "openai";
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
// Direct OpenAI EU Data Residency Endpoint:
baseURL: "
https://eu.api.openai.com/v1",
});
Note: OpenAI requires an API Project/Organization explicitly created in the EU region in your OpenAI platform
settings for eu.api.openai.com requests to be accepted.
Step 2: Update the OpenAI Realtime WebSocket Endpoint (If Applicable)
Because examples/openai-realtime connects to the OpenAI Realtime API via WebSocket connections
(wss://), check where the WebSocket connection is established.
1. Look for the WebSocket instantiation string or base host URL configuration (e.g.,
wss://[api.openai.com/v1/realtime](https://api.openai.com/v1/realtime)).
2. Update the WebSocket host to the EU target:
// Standard Global WebSocket Endpoint:
// const wsUrl = "wss://api.openai.com/v1/realtime?model=gpt-4o-realtime-preview";
// EU Data Residency WebSocket Endpoint:
const wsUrl = "wss://eu.api.openai.com/v1/realtime?model=gpt-4o-realtime-preview";
Step 3: Pass via Configuration File (config.yaml or .env)
The recommended pattern in agentic-call-control is to avoid hardcoding API URLs. You can expose this
as a configurable setting in config.yaml:
1. Edit your config.yaml:
appId: "YOUR_3CX_APP_ID"
appSecret: "YOUR_3CX_APP_SECRET"
pbxBase: "
https://your-pbx-domain.com"
openaiApiKey: "sk-proj-..."
# Add custom base URL parameter
openaiBaseUrl: "
https://eu.api.openai.com/v1"
2. Pass openaiBaseUrl from your configuration into the client initialization:
const openai = new OpenAI({
apiKey: config.openaiApiKey,
baseURL: config.openaiBaseUrl || "
https://api.openai.com/v1",
});
Alternative: Azure OpenAI Service in EU Regions
If you are using Azure OpenAI Service (which provides guaranteed EU data processing via regions like
sweden-central or france-central), configure the AzureOpenAI client SDK instead:
import { AzureOpenAI } from "openai";
const openai = new AzureOpenAI({
apiKey: process.env.AZURE_OPENAI_API_KEY,
endpoint: "https://<your-resource-name>.openai.azure.com/", // EU Region Endpoint
apiVersion: "2024-10-01-preview",
deployment: "gpt-4o-realtime-preview",
});
Compliance Verification Checklist
1. OpenAI Organization Settings: Ensure your project is set to the Europe region inside the OpenAI
Platform Dashboard. Standard api.openai.com traffic routes to US servers by default.
2. Data Processing Agreement (DPA): Confirm a signed DPA with OpenAI or Microsoft Azure to satisfy
GDPR requirements for processing personal caller data over the PBX.
3. Recording & Audio Transcripts: Ensure audio recordings and transcriptions generated by agentic-
call-control are stored within compliant EU storage backends.