API Usage Guide¶
Overview¶
The DjangoPBX API is a RESTful API built using Django REST Framework that provides comprehensive access to the PBX system’s functionality. All API endpoints are prefixed with /api/ and support standard HTTP methods (GET, POST, PUT, PATCH, DELETE).
Base URL¶
https://your-pbx-domain.com/api/
Key Features¶
Token-based authentication
Automatic pagination (25 items per page)
Comprehensive filtering and search capabilities
Support for JSON and CSV response formats
Granular permission system based on user groups
Authentication¶
The API uses Token Authentication as the primary authentication method. You’ll need to obtain an authentication token before making API requests.
Obtaining an Authentication Token¶
# Request a token
curl -X POST https://your-pbx-domain.com/api-auth/login/ \
-H "Content-Type: application/json" \
-d '{"username": "your-username", "password": "your-password"}'
Using the Token¶
Include the token in the Authorization header for all subsequent requests:
curl -H "Authorization: Token your-auth-token" \
https://your-pbx-domain.com/api/extensions/
Permission Groups¶
The API uses three permission groups:
user_api: Basic user access - can view and manage their own extensions and settings
minor_admin_api: Domain-level admin - can manage resources within their domain
admin_api: Full admin access - can manage all system resources
API Endpoints¶
Complete Endpoint Reference¶
Module |
Endpoint |
Methods |
Description |
|---|---|---|---|
Accounts |
|
GET, POST, PUT, PATCH, DELETE |
Manage extensions |
|
GET |
Customer view of extensions (read-only) |
|
|
GET, POST |
Link extensions to users |
|
|
GET, POST |
Follow-me routing |
|
|
GET, POST |
SIP trunk gateways |
|
|
GET, POST |
Bridge configurations |
|
Users & Tenants |
|
GET, POST, PUT, PATCH, DELETE |
User management |
|
GET, POST |
User groups |
|
|
GET, POST |
Domain/tenant management |
|
|
GET, POST |
User profiles |
|
|
GET, POST |
System-wide settings |
|
|
GET, POST |
Domain-specific settings |
|
Call Records |
|
GET |
Call Detail Records |
|
GET |
Customer CDR view |
|
|
GET |
CDR statistics |
|
|
GET |
Call timeline visualization |
|
Voicemail |
|
GET, POST, PUT, PATCH, DELETE |
Voicemail boxes |
|
GET, POST |
Voicemail messages |
|
|
GET, POST |
Greeting management |
|
Dialplans |
|
GET, POST |
Dialplan rules |
|
GET, POST |
Inbound routes |
|
|
GET, POST |
Outbound routes |
|
|
GET, POST |
Time-based routing |
|
Other |
|
POST |
Click-to-dial functionality |
|
GET, POST |
Recording management |
|
|
GET, POST |
Call center queues |
|
|
GET, POST |
Ring groups |
|
|
GET, POST |
IVR menus |
Request & Response Formats¶
Standard List Response¶
{
"count": 100,
"next": "https://your-pbx-domain.com/api/extensions/?page=2",
"previous": null,
"results": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://your-pbx-domain.com/api/extensions/550e8400-e29b-41d4-a716-446655440000/",
"extension": "1001",
"domain_id": "660e8400-e29b-41d4-a716-446655440000",
"enabled": true
}
]
}
Standard Detail Response¶
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://your-pbx-domain.com/api/extensions/550e8400-e29b-41d4-a716-446655440000/",
"extension": "1001",
"password": "secure-password",
"domain_id": "660e8400-e29b-41d4-a716-446655440000",
"enabled": true,
"created": "2024-01-01T00:00:00Z",
"updated": "2024-01-15T12:30:00Z",
"updated_by": "admin"
}
Error Response¶
{
"error": 400,
"message": "Bad Request",
"detail": {
"extension": ["This field is required."]
}
}
Core API Resources¶
Extensions API¶
Extensions are the core of the PBX system. Each extension represents a phone endpoint.
Create Extension¶
curl -X POST https://your-pbx-domain.com/api/extensions/ \
-H "Authorization: Token your-auth-token" \
-H "Content-Type: application/json" \
-d '{
"domain_id": "660e8400-e29b-41d4-a716-446655440000",
"extension": "1001",
"password": "secure-password-123",
"effective_caller_id_name": "John Doe",
"effective_caller_id_number": "1001",
"enabled": true
}'
Update Extension Settings¶
curl -X PATCH https://your-pbx-domain.com/api/extensions/550e8400-e29b-41d4-a716-446655440000/ \
-H "Authorization: Token your-auth-token" \
-H "Content-Type: application/json" \
-d '{
"forward_all_enabled": true,
"forward_all_destination": "1002",
"do_not_disturb": false
}'
Extension Fields Reference¶
Field |
Type |
Required |
Description |
|---|---|---|---|
domain_id |
UUID |
Yes |
Domain this extension belongs to |
extension |
String |
Yes |
Extension number |
password |
String |
Yes |
SIP password |
effective_caller_id_name |
String |
No |
Display name for outbound calls |
effective_caller_id_number |
String |
No |
Number shown for outbound calls |
forward_all_enabled |
Boolean |
No |
Enable call forwarding |
forward_all_destination |
String |
No |
Forward destination |
do_not_disturb |
Boolean |
No |
DND status |
enabled |
Boolean |
No |
Extension active status (default: true) |
limit_max |
Integer |
No |
Max concurrent calls |
toll_allow |
String |
No |
Allowed call types |
hold_music |
String |
No |
Music on hold selection |
Call Detail Records (CDR)¶
CDRs provide detailed information about all calls in the system.
Query CDRs¶
# Get CDRs for last 24 hours
curl -G https://your-pbx-domain.com/api/xmlcdrs/ \
-H "Authorization: Token your-auth-token" \
--data-urlencode "start_stamp__gte=2024-01-15T00:00:00Z" \
--data-urlencode "start_stamp__lt=2024-01-16T00:00:00Z"
# Get CDRs for specific extension
curl -G https://your-pbx-domain.com/api/xmlcdrs/ \
-H "Authorization: Token your-auth-token" \
--data-urlencode "extension_id=550e8400-e29b-41d4-a716-446655440000"
# Get summary only (exclude large XML/JSON fields)
curl -G https://your-pbx-domain.com/api/xmlcdrs/?nojson&noxml \
-H "Authorization: Token your-auth-token"
Export CDRs to CSV¶
curl -G https://your-pbx-domain.com/api/xmlcustomercdrs/download/ \
-H "Authorization: Token your-auth-token" \
--data-urlencode "start_stamp__gte=2024-01-15T00:00:00Z" \
--data-urlencode "start_stamp__lt=2024-01-16T00:00:00Z" \
-o cdrs.csv
CDR Fields¶
Field |
Type |
Description |
|---|---|---|
call_uuid |
UUID |
Unique call identifier |
direction |
String |
inbound/outbound |
caller_id_name |
String |
Caller name |
caller_id_number |
String |
Caller number |
destination_number |
String |
Called number |
start_stamp |
DateTime |
Call start time |
answer_stamp |
DateTime |
Call answer time |
end_stamp |
DateTime |
Call end time |
duration |
Integer |
Total call duration (seconds) |
billsec |
Integer |
Billable duration (seconds) |
hangup_cause |
String |
Reason for call termination |
record_path |
String |
Path to call recording |
Voicemail API¶
Manage voicemail boxes and messages.
Create Voicemail Box¶
curl -X POST https://your-pbx-domain.com/api/voicemails/ \
-H "Authorization: Token your-auth-token" \
-H "Content-Type: application/json" \
-d '{
"extension_id": "550e8400-e29b-41d4-a716-446655440000",
"password": "1234",
"mail_to": "user@example.com",
"attach_file": true,
"enabled": true
}'
Retrieve Voicemail Messages¶
curl https://your-pbx-domain.com/api/voicemail_messages/ \
-H "Authorization: Token your-auth-token"
Gateways (SIP Trunks)¶
Configure external SIP trunks for outbound calling.
Create Gateway¶
curl -X POST https://your-pbx-domain.com/api/gateways/ \
-H "Authorization: Token your-auth-token" \
-H "Content-Type: application/json" \
-d '{
"domain_id": "660e8400-e29b-41d4-a716-446655440000",
"gateway": "provider-trunk",
"username": "trunk-username",
"password": "trunk-password",
"proxy": "sip.provider.com",
"register": true,
"enabled": true
}'
Dialplan Routes¶
Configure call routing rules.
Create Inbound Route¶
curl -X POST https://your-pbx-domain.com/api/dialplan_ib_route/ \
-H "Authorization: Token your-auth-token" \
-H "Content-Type: application/json" \
-d '{
"domain_id": "660e8400-e29b-41d4-a716-446655440000",
"name": "Main Number",
"number": "+1234567890",
"destination_number": "1001",
"enabled": true
}'
Create Outbound Route¶
curl -X POST https://your-pbx-domain.com/api/dialplan_ob_route/ \
-H "Authorization: Token your-auth-token" \
-H "Content-Type: application/json" \
-d '{
"domain_id": "660e8400-e29b-41d4-a716-446655440000",
"name": "International Calls",
"prefix": "011",
"gateway_id": "770e8400-e29b-41d4-a716-446655440000",
"enabled": true
}'
Advanced Features¶
Click-to-Dial¶
Initiate calls between two endpoints programmatically.
curl -X POST https://your-pbx-domain.com/api/clickdial/ \
-H "Authorization: Token your-auth-token" \
-H "Content-Type: application/json" \
-d '{
"dest": "1002",
"host": "switch1"
}'
Call Statistics¶
Get aggregated call statistics for analysis.
curl -G https://your-pbx-domain.com/api/xmlcdrbasicstatistics/ \
-H "Authorization: Token your-auth-token" \
--data-urlencode "cdr_extn=1001" \
--data-urlencode "cdr_hours=24" \
--data-urlencode "cdr_scope=extn"
Response includes:
Total call count
Missed calls
Average/max ring time
Average/max call duration
Hourly call distribution
Bulk Operations¶
Some endpoints support bulk operations using custom actions.
Flush All Directory Caches¶
curl -X POST https://your-pbx-domain.com/api/extensions/flush_cache_all_directories/ \
-H "Authorization: Token your-auth-token"
Filtering and Searching¶
Use query parameters to filter results:
# Filter extensions by domain
curl -G https://your-pbx-domain.com/api/extensions/ \
-H "Authorization: Token your-auth-token" \
--data-urlencode "domain_id=660e8400-e29b-41d4-a716-446655440000"
# Search extensions by number
curl -G https://your-pbx-domain.com/api/extensions/ \
-H "Authorization: Token your-auth-token" \
--data-urlencode "extension__contains=100"
# Order results
curl -G https://your-pbx-domain.com/api/extensions/ \
-H "Authorization: Token your-auth-token" \
--data-urlencode "ordering=extension"
Pagination¶
Navigate through large result sets:
# Get second page of results
curl https://your-pbx-domain.com/api/extensions/?page=2 \
-H "Authorization: Token your-auth-token"
# Change page size (max 100)
curl https://your-pbx-domain.com/api/extensions/?page_size=50 \
-H "Authorization: Token your-auth-token"
Error Handling¶
The API returns standard HTTP status codes:
Status Code |
Description |
|---|---|
200 OK |
Request successful |
201 Created |
Resource created successfully |
204 No Content |
Resource deleted successfully |
400 Bad Request |
Invalid request data |
401 Unauthorized |
Authentication required or failed |
403 Forbidden |
Insufficient permissions |
404 Not Found |
Resource not found |
500 Internal Server Error |
Server error |
Common Error Scenarios¶
Invalid Authentication¶
{
"detail": "Invalid token."
}
Validation Error¶
{
"extension": ["Extension with this number already exists."],
"password": ["This field is required."]
}
Permission Denied¶
{
"detail": "You do not have permission to perform this action."
}
Code Examples¶
Python Example¶
import requests
class DjangoPBXAPI:
def __init__(self, base_url, token):
self.base_url = base_url.rstrip('/')
self.headers = {
'Authorization': f'Token {token}',
'Content-Type': 'application/json'
}
def get_extensions(self, domain_id=None):
url = f"{self.base_url}/api/extensions/"
params = {'domain_id': domain_id} if domain_id else {}
response = requests.get(url, headers=self.headers, params=params)
response.raise_for_status()
return response.json()
def create_extension(self, data):
url = f"{self.base_url}/api/extensions/"
response = requests.post(url, headers=self.headers, json=data)
response.raise_for_status()
return response.json()
def get_cdrs(self, start_date, end_date, extension_id=None):
url = f"{self.base_url}/api/xmlcdrs/"
params = {
'start_stamp__gte': start_date,
'start_stamp__lt': end_date
}
if extension_id:
params['extension_id'] = extension_id
response = requests.get(url, headers=self.headers, params=params)
response.raise_for_status()
return response.json()
# Usage
api = DjangoPBXAPI('https://your-pbx-domain.com', 'your-auth-token')
# Get all extensions
extensions = api.get_extensions()
# Create new extension
new_ext = api.create_extension({
'domain_id': '660e8400-e29b-41d4-a716-446655440000',
'extension': '1099',
'password': 'secure-pass-123',
'enabled': True
})
# Get today's CDRs
from datetime import datetime, date
cdrs = api.get_cdrs(
start_date=date.today().isoformat(),
end_date=datetime.now().isoformat()
)
JavaScript Example¶
class DjangoPBXAPI {
constructor(baseUrl, token) {
this.baseUrl = baseUrl.replace(/\/$/, '');
this.headers = {
'Authorization': `Token ${token}`,
'Content-Type': 'application/json'
};
}
async getExtensions(domainId = null) {
const params = domainId ? `?domain_id=${domainId}` : '';
const response = await fetch(`${this.baseUrl}/api/extensions/${params}`, {
headers: this.headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async createExtension(data) {
const response = await fetch(`${this.baseUrl}/api/extensions/`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async clickToDial(destination, host = null) {
const data = { dest: destination };
if (host) data.host = host;
const response = await fetch(`${this.baseUrl}/api/clickdial/`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
}
// Usage
const api = new DjangoPBXAPI('https://your-pbx-domain.com', 'your-auth-token');
// Get extensions
api.getExtensions()
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// Create extension
api.createExtension({
domain_id: '660e8400-e29b-41d4-a716-446655440000',
extension: '1099',
password: 'secure-pass-123',
enabled: true
})
.then(data => console.log('Created:', data))
.catch(error => console.error('Error:', error));
// Click to dial
api.clickToDial('1002')
.then(data => console.log('Dialing:', data))
.catch(error => console.error('Error:', error));
Bash/cURL Example Script¶
#!/bin/bash
# Configuration
API_URL="https://your-pbx-domain.com/api"
API_TOKEN="your-auth-token"
# Function to make API calls
api_call() {
local method=$1
local endpoint=$2
local data=$3
if [ -z "$data" ]; then
curl -X $method "${API_URL}${endpoint}" \
-H "Authorization: Token ${API_TOKEN}" \
-H "Content-Type: application/json"
else
curl -X $method "${API_URL}${endpoint}" \
-H "Authorization: Token ${API_TOKEN}" \
-H "Content-Type: application/json" \
-d "$data"
fi
}
# Get all extensions
echo "Getting extensions..."
api_call GET "/extensions/"
# Create new extension
echo -e "\n\nCreating new extension..."
api_call POST "/extensions/" '{
"domain_id": "660e8400-e29b-41d4-a716-446655440000",
"extension": "1099",
"password": "secure-pass-123",
"enabled": true
}'
# Get CDRs for today
echo -e "\n\nGetting today's CDRs..."
TODAY=$(date -u +%Y-%m-%dT00:00:00Z)
TOMORROW=$(date -u -d tomorrow +%Y-%m-%dT00:00:00Z)
api_call GET "/xmlcdrs/?start_stamp__gte=${TODAY}&start_stamp__lt=${TOMORROW}"
Best Practices¶
Authentication Security¶
Store tokens securely (environment variables, secure vaults)
Rotate tokens regularly
Never commit tokens to version control
Rate Limiting¶
Implement exponential backoff for retries
Cache responses when appropriate
Use bulk endpoints when available
Error Handling¶
Always check response status codes
Implement proper error logging
Provide meaningful error messages to users
Performance¶
Use field filtering to reduce payload size (
?fields=id,extension)Implement pagination for large datasets
Use appropriate query filters to limit results
Data Validation¶
Validate input data before sending to API
Handle validation errors gracefully
Use the API’s validation messages in your UI
Troubleshooting¶
Common Issues¶
401 Unauthorized
Check token validity
Ensure token is included in Authorization header
Verify token format:
Token <your-token>
403 Forbidden
Verify user has appropriate permission group
Check if resource belongs to user’s domain
Ensure user is active and enabled
400 Bad Request
Check request data format (valid JSON)
Verify all required fields are included
Check field data types match API expectations
500 Internal Server Error
Check API logs for detailed error
Verify database connectivity
Contact system administrator
Debug Tips¶
Use verbose curl output:
curl -vCheck response headers for additional info
Use API introspection endpoints when available
Test with minimal required fields first
Verify UUID formats are valid
Conclusion¶
The DjangoPBX API provides comprehensive access to all PBX functionality through a well-structured RESTful interface. By following this guide and the examples provided, you should be able to integrate with all aspects of the system effectively.
For additional support or to report issues, please contact your system administrator or refer to the DjangoPBX documentation.