English English العربية العربية Español Español Français Français Deutsch Deutsch Português Português 中文 中文 日本語 日本語 Türkçe Türkçe Русский Русский

API Documentation

Integrate VOIP@ Cloud into your applications. Manage domains, extensions, gateways, and call records programmatically with our REST API.

Try the Live API Demo

Explore and test all API endpoints interactively in your browser — no setup required.

Open Live Demo View Source

Overview

The VOIP@ Cloud API is a RESTful API that uses JSON for request and response bodies. All API endpoints are served over HTTPS. The base URL for all API requests is:

https://mt.voipat.com/pbxapi

All requests must include the Content-Type: application/json header. Responses follow standard HTTP status codes: 200 for success, 201 for created, 400 for bad request, 401 for unauthorized, 404 for not found, and 503 for ESL/FreeSWITCH not connected.

A Swagger / OpenAPI interactive reference is available at: https://mt.voipat.com/pbxapi/api-docs

Authentication

All API requests require authentication using a Bearer token. You can generate API keys from your VOIP@ Cloud dashboard under Accounts > Users.

Step 1 — Get your API Key

  • Log in to your VOIP@ Cloud dashboard
  • Navigate to Accounts > Users
  • Open the user and scroll to the API Key field
  • Click Generate — the key starts with fpx_
  • Copy and store the key securely

Step 2 — Exchange key for a Bearer token

POST /pbxapi/auth/token Exchange API key for a short-lived JWT
curl -X POST https://mt.voipat.com/pbxapi/auth/token \ -H "Content-Type: application/json" \ -d '{"api_key": "fpx_your_key_here", "domain": "pbx.example.com"}'
Response 200
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "expires_in": "24h", "token_type": "Bearer", "domain": "pbx.example.com", "username": "john.doe" }

Step 3 — Use the token in all requests

# Use the Bearer token in every request curl https://mt.voipat.com/pbxapi/domains \ -H "Authorization: Bearer YOUR_JWT_TOKEN" # Or use your API key directly (also accepted) curl https://mt.voipat.com/pbxapi/domains \ -H "X-API-Key: fpx_your_key_here"

API keys are scoped to the user's domain. You can regenerate or revoke keys at any time from the user's profile.

Endpoints

Status

GET /pbxapi/status Health check — no auth required
curl https://mt.voipat.com/pbxapi/status
Response 200
{ "status": "ok", "service": "FusionPBX API Bridge", "version": "1.0.0", "timestamp": "2026-03-28T10:00:00.000Z" }
GET /pbxapi/status/detailed ESL + DB + WebSocket status (auth required)
Response 200
{ "status": "ok", "services": { "esl": { "connected": true }, "database": { "connected": true }, "websocket": { "connectedClients": 3 } } }

Domains

GET /pbxapi/domains List all FusionPBX domains
curl https://mt.voipat.com/pbxapi/domains \ -H "Authorization: Bearer TOKEN"
Response 200
{ "domains": [ { "domain_uuid": "...", "domain_name": "pbx.example.com", "domain_enabled": "true" } ], "count": 1 }

Extensions

GET /pbxapi/extensions?domain=pbx.example.com List all extensions for a domain
Response 200
{ "extensions": [ { "extension": "1001", "effective_caller_id_name": "John Doe", "enabled": "true" } ], "count": 12 }
GET /pbxapi/extensions/:ext?domain=pbx.example.com Get a specific extension by number

Returns full extension details. Returns 404 if not found.

GET /pbxapi/extensions/registrations?domain=pbx.example.com Get registered SIP endpoints (online/offline)
Response 200
{ "registrations": [ { "reg_user": "1001", "reg_host": "pbx.example.com", "status": "Registered" } ] }

Calls (Real-time Control)

All call control routes communicate with FreeSWITCH via ESL. Returns 503 if ESL is not connected.

GET /pbxapi/calls/active?domain=pbx.example.com Get all active (bridged) calls
Response 200
{ "calls": [ { "uuid": "abc-123", "caller_id_number": "1001", "destination_number": "+14155551234", "duration": 45 } ], "count": 1 }
GET /pbxapi/calls/channels?domain=pbx.example.com Get all active channel legs

Returns individual channel legs (2 per bridged call). Use /calls/active for paired calls.

GET /pbxapi/calls/channels/:uuid Get info about a specific channel by UUID

Returns 404 if the channel UUID is not found or the call has ended.

POST /pbxapi/calls/originate Originate (make) a new call
curl -X POST https://mt.voipat.com/pbxapi/calls/originate \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{ "from": "1001", "to": "+14155551234", "domain": "pbx.example.com", "callerId": "+12025550100", "timeout": 30 }'
Response 200
{ "uuid": "abc-123", "message": "Call from 1001 to +14155551234 initiated" }
POST /pbxapi/calls/:uuid/hangup Hangup a call
curl -X POST https://mt.voipat.com/pbxapi/calls/abc-123/hangup \ -H "Authorization: Bearer TOKEN" \ -d '{"cause": "NORMAL_CLEARING"}'
POST /pbxapi/calls/:uuid/transfer Transfer a call (blind or attended)
curl -X POST https://mt.voipat.com/pbxapi/calls/abc-123/transfer \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"destination": "1002", "domain": "pbx.example.com", "type": "blind"}'

type: "blind" (default) or "attended"

POST /pbxapi/calls/:uuid/hold Hold / Unhold / Toggle hold

Also available: POST /pbxapi/calls/:uuid/unhold and POST /pbxapi/calls/:uuid/hold/toggle

POST /pbxapi/calls/:uuid/dtmf Send DTMF tones
-d '{"digits": "1234#"}'
POST /pbxapi/calls/:uuid/mute Mute / Unmute a channel

Also available: POST /pbxapi/calls/:uuid/unmute

Call Detail Records (CDR)

GET /pbxapi/cdr Get CDR records with filters

Query parameters: domain, start_date, end_date, direction (inbound/outbound/local), extension, search, limit (max 1000), offset

curl "https://mt.voipat.com/pbxapi/cdr?domain=pbx.example.com&start_date=2026-03-01&direction=outbound&limit=50" \ -H "Authorization: Bearer TOKEN"
Response 200
{ "records": [ { "xml_cdr_uuid": "...", "caller_id_number": "1001", "destination_number": "+14155551234", "direction": "outbound", "duration": 245, "start_stamp": "2026-03-15T14:22:10Z", "hangup_cause": "NORMAL_CLEARING" } ], "total": 342, "limit": 50, "offset": 0 }
GET /pbxapi/cdr/stats/summary Call statistics summary

Query parameters: domain, start_date, end_date

Response 200
{ "stats": { "total_calls": 342, "answered": 298, "missed": 44, "avg_duration": 187 } }

API Key Management

POST /pbxapi/apikeys Create an API key for a user
curl -X POST https://mt.voipat.com/pbxapi/apikeys \ -H "Authorization: Bearer TOKEN" \ -H "Content-Type: application/json" \ -d '{"username": "john.doe", "domain": "pbx.example.com", "description": "CRM Production"}'
Response 201
{ "plain_key": "fpx_a1b2c3...", "warning": "Save the plain_key immediately — it will not be shown again." }
GET /pbxapi/apikeys?domain=pbx.example.com List API keys for a domain

Non-admin users see only keys in their own domain.

DELETE /pbxapi/apikeys/:uuid Revoke an API key immediately

The key is invalidated instantly — no waiting for token expiry.

PATCH /pbxapi/apikeys/:uuid Enable or disable a key
-d '{"enabled": false}'

CRM Integration

VOIP@ Cloud provides three integration points to connect the WebRTC phone with any CRM, helpdesk, or business application. Choose the option that fits your architecture.

How it works:

Phone widget (browser) → calls crm_webhook_proxy.php on every call event → server replaces placeholders → server POSTs or GETs your CRM URL → your CRM receives the event data.

Configure in: FusionPBX → Apps → WebRTC Phone → CRM Settings

Option 1 — CRM Webhook (real-time call events)

The phone widget fires call events to the server-side webhook proxy, which forwards them to your configured CRM URL with all call data substituted in.

POST /app/webrtc_phone/crm_webhook_proxy.php Called by the phone widget on every call event

Query parameters (sent by the phone widget):

ParameterRequiredDescription
eventYesnew_call, ringing, dial_out, answered, hangup, agent_login, agent_logout
caller_idNoCaller's phone number
caller_nameNoCaller's display name
destinationNoDialed destination number
directionNoinbound or outbound
durationNoCall duration in seconds (sent on hangup)
extensionNoAgent's extension number
call_idNoUnique SIP Call-ID
timestampNoISO 8601 event timestamp
Response 200
{ "ok": true, "http_code": 200, "event": "answered" }

CRM URL placeholders — use in your configured webhook and screen-pop URLs:

PlaceholderDescription
{event}Event name: new_call, ringing, dial_out, answered, hangup, agent_login, agent_logout
{caller_id}Caller's phone number
{caller_name}Caller's display name (if available)
{destination}Dialed destination number
{direction}inbound or outbound
{duration}Call duration in seconds (available on hangup)
{extension}Agent's extension number
{call_id}Unique SIP Call-ID
{timestamp}ISO 8601 timestamp of the event
{domain}FusionPBX domain name (e.g. pbx.example.com)

CRM URL settings — configure in Apps → WebRTC Phone → CRM Settings:

SettingDescription
crm_urlWebhook URL called on all call events (use placeholders above)
crm_methodGET or POST. On POST, data is also sent as JSON body
crm_login_urlScreen-pop URL opened in browser on incoming call
crm_auto_login_urlURL opened automatically when the phone registers
crm_agent_login_urlCalled when agent activates agent_login event
crm_agent_logout_urlCalled when agent activates agent_logout event
# Example: Salesforce webhook URL with placeholders https://yourinstance.salesforce.com/services/apexrest/calls?event={event}&from={caller_id}&ext={extension}&id={call_id} # Example: screen-pop to open contact record on incoming call https://crm.example.com/contacts/search?phone={caller_id}&agent={extension}

Option 2 — Session API (read CRM config)

Returns the active user's extensions, WSS config, and all configured CRM URLs. Requires a logged-in FusionPBX session. Used internally by the phone widget but also available to custom integrations.

GET /app/webrtc_phone/webrtc_phone_api.php Session-authenticated — returns extensions + full CRM config
Response 200
{ "domain": "pbx.example.com", "wss_port": "7443", "stun_server": "stun:stun.l.google.com:19302", "crm_url": "https://crm.example.com/webhook?event={event}&from={caller_id}", "crm_method": "GET", "crm_login_url": "https://crm.example.com/contacts?phone={caller_id}", "crm_auto_login_url": "", "crm_agent_login_url": "", "crm_agent_logout_url": "", "extensions": [ { "extension": "1001", "password": "••••••••", "caller_id_name": "John Doe", "caller_id_number": "1001" } ] }

Option 3 — Click-to-Dial API (embed phone in external sites)

Allows any external website or CRM to embed a call button that dials directly from the user's browser — no FusionPBX login required.

GET /app/webrtc_phone/click_to_dial/click_to_dial_api.php Token-authenticated — returns extension credentials for embedding
# Pass token via header (recommended) curl -H "X-CTD-Token: YOUR_TOKEN" \ https://mt.voipat.com/app/webrtc_phone/click_to_dial/click_to_dial_api.php # Or pass token as query parameter https://mt.voipat.com/app/webrtc_phone/click_to_dial/click_to_dial_api.php?token=YOUR_TOKEN
Response 200
{ "domain": "pbx.example.com", "wss_port": "7443", "extension": "1001", "password": "••••••••", "caller_id_name": "Sales Line", "button_color": "#1a73e8", "button_label": "Call Us", "destination_number": "+12025551234" }

CORS: Supports cross-origin requests. Restrict to your domain by setting Allowed Origins when creating the token in FusionPBX.


API Tester

Test API endpoints directly from this page. Enter your API key and domain to authenticate, then select an endpoint and send a request.

Requests go directly to mt.voipat.com. CORS must be enabled on the API server for cross-origin requests from this page to succeed.

Rate Limiting

To ensure fair usage and platform stability, API requests are rate limited per API key.

Rate Limits

Standard plans: 60 requests per minute, 1,000 requests per hour

Enterprise plans: 300 requests per minute, 10,000 requests per hour

Rate limit information is included in the response headers:

X-RateLimit-Limit: 60 X-RateLimit-Remaining: 45 X-RateLimit-Reset: 1711036800

If you exceed the rate limit, you will receive a 429 Too Many Requests response. Wait until the X-RateLimit-Reset timestamp before retrying. We recommend implementing exponential backoff in your integration.

Need Help?

If you have questions about the API or need assistance with your integration, contact our developer support team: