nextgenswitch / nextgenswitch-php
Official PHP SDK for the NextGenSwitch Programmable Voice API and Voice XML.
Package info
github.com/nextgenswitch/nextgenswitch-php
pkg:composer/nextgenswitch/nextgenswitch-php
This package is not auto-updated.
Last update: 2026-07-28 19:36:02 UTC
README
The official PHP SDK for the NextGenSwitch Programmable Voice API. Create and modify calls, build escaped Voice XML, stream call audio to AI services, and parse Gather and Dial callbacks with typed PHP objects.
Requirements
- PHP 8.1 or newer
- DOM extension
- Composer
- A NextGenSwitch deployment and API credentials
Installation
composer require nextgenswitch/nextgenswitch-php
Configure the Client
Keep credentials in environment variables or a secret manager.
use NextGenSwitch\Client; $client = new Client( baseUrl: getenv('NEXTGENSWITCH_BASE_URL'), authorizationCode: getenv('NEXTGENSWITCH_AUTHORIZATION'), authorizationSecret: getenv('NEXTGENSWITCH_AUTHORIZATION_SECRET'), );
The SDK sends credentials with the X-Authorization and X-Authorization-Secret headers documented by NextGenSwitch. Use HTTPS for remote deployments.
Create a Call
Use either inline Voice XML or a URL that returns a valid <Response>.
use NextGenSwitch\VoiceResponse; $voice = (new VoiceResponse()) ->say('Welcome to NextGenSwitch.') ->gather( [ 'action' => 'https://example.com/gather', 'method' => 'POST', 'numDigits' => 1, 'timeout' => 10, ], static fn ($gather) => $gather->say('Press one for sales.'), ); $result = $client->createCall( to: '2001', from: '1001', responseXml: $voice, statusCallback: 'https://example.com/call-status', ); $call = $result->data();
To use a hosted XML document:
$result = $client->createCall( to: '2001', from: '1001', responseUrl: 'https://example.com/call-flow.xml', );
Exactly one of responseXml or responseUrl is required.
Modify an Active Call
$updatedFlow = (new VoiceResponse()) ->pause(2) ->say('Your call flow has been updated.') ->dial('1000'); $client->modifyCall('CALL-123', $updatedFlow);
Build Voice XML
$response = (new VoiceResponse()) ->say('This is a test.', ['loop' => 2]) ->play('https://example.com/audio.mp3', ['loop' => 1]) ->record([ 'action' => 'https://example.com/recording', 'method' => 'POST', 'timeout' => 5, 'finishOnKey' => '#', 'beep' => true, ]) ->hangup(); header('Content-Type: application/xml; charset=UTF-8'); echo $response->xml();
Supported helpers match the official API documentation:
| XML verb | SDK method |
|---|---|
<Say> |
say($text, $attributes) |
<Play> |
play($url, $attributes) |
<Gather> |
gather($attributes, $children) |
<Dial> |
dial($to, $attributes, $children) |
<Record> |
record($attributes) |
<Connect><Stream> |
stream($url, $parameters, $attributes) |
<Hangup> |
hangup() |
<Pause> |
pause($seconds) |
<Redirect> |
redirect($url, $method) |
<Bridge> |
bridge($callId, $bridgeAfterEstablish) |
<Leave> |
leave() |
Text and attribute values are encoded through PHP's DOM implementation instead of string concatenation.
Stream Audio to an AI Service
$response = (new VoiceResponse())->stream( url: 'wss://voice.example.com/session', parameters: [ 'session_id' => 'session-123', 'tenant' => 'example', ], attributes: ['name' => 'assistant-stream'], );
Do not put provider API keys in Voice XML. Resolve secrets on the WebSocket service.
Parse Action Callbacks
use NextGenSwitch\Webhook\GatherResult; $gather = GatherResult::fromArray($_POST); if ($gather->digits === '1') { echo (new VoiceResponse())->dial('1001')->xml(); } else { echo (new VoiceResponse())->say('No valid selection received.')->hangup()->xml(); }
Dial callbacks can be parsed with DialResult::fromArray($_POST). Its established, duration, waitingDuration, bridgeCallId, and recordFile properties correspond to the documented callback fields.
Callback authenticity controls are deployment-specific and are not currently documented as a NextGenSwitch signature scheme. Restrict callback endpoints, require TLS, validate expected fields, and apply your own authentication controls where supported.
Errors
ValidationException: invalid SDK input before a request is sentApiException: a non-2xx API response; exposesstatusCode()andresponseBody()NextGenSwitchException: transport or other SDK failure
use NextGenSwitch\Exception\ApiException; try { $client->modifyCall('CALL-123', (new VoiceResponse())->hangup()); } catch (ApiException $error) { error_log($error->statusCode() . ': ' . $error->getMessage()); }
Runnable Examples
After composer install, configure credentials without committing them:
export NEXTGENSWITCH_BASE_URL="https://your-switch.example.com" export NEXTGENSWITCH_AUTHORIZATION="your-authorization-code" export NEXTGENSWITCH_AUTHORIZATION_SECRET="your-authorization-secret"
Then run or adapt these examples:
| Example | Purpose |
|---|---|
create-call.php |
Create a call with inline Gather instructions |
modify-call.php |
Replace the flow of an active call by call ID |
record-call.php |
Record caller audio with beep, transcription, trimming, and callback |
dial-with-recording.php |
Dial an external destination and record from answer |
stream-to-ai-agent.php |
Stream bidirectional audio to a WebSocket AI service |
gather-webhook.php |
Parse Gather input and return the next Voice XML flow |
dial-webhook.php |
Parse Dial completion and return follow-up Voice XML |
For example:
php examples/create-call.php php examples/record-call.php php examples/modify-call.php CALL-123
Replace all example.com callback, media, and WebSocket URLs with TLS endpoints you control. Validate callback input and never commit API or SIP credentials.
Development
composer install
composer validate --strict
composer lint
composer test
The test workflow covers PHP 8.1, 8.2, 8.3, and 8.4.
Documentation and Support
- Programmable Voice API
- NextGenSwitch documentation
- NextGenSwitch website
- Report an SDK issue
- Contact NextGenSwitch