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

API Endpoints

Module

Endpoint

Methods

Description

Accounts

/api/extensions/

GET, POST, PUT, PATCH, DELETE

Manage extensions

/api/customerextensions/

GET

Customer view of extensions (read-only)

/api/extensionuser/

GET, POST

Link extensions to users

/api/follow_me_destinations/

GET, POST

Follow-me routing

/api/gateways/

GET, POST

SIP trunk gateways

/api/bridges/

GET, POST

Bridge configurations

Users & Tenants

/api/users/

GET, POST, PUT, PATCH, DELETE

User management

/api/groups/

GET, POST

User groups

/api/domains/

GET, POST

Domain/tenant management

/api/profiles/

GET, POST

User profiles

/api/default_settings/

GET, POST

System-wide settings

/api/domain_settings/

GET, POST

Domain-specific settings

Call Records

/api/xmlcdrs/

GET

Call Detail Records

/api/xmlcustomercdrs/

GET

Customer CDR view

/api/xmlcdrbasicstatistics/

GET

CDR statistics

/api/calltimeline/

GET

Call timeline visualization

Voicemail

/api/voicemails/

GET, POST, PUT, PATCH, DELETE

Voicemail boxes

/api/voicemail_messages/

GET, POST

Voicemail messages

/api/voicemail_greetings/

GET, POST

Greeting management

Dialplans

/api/dialplans/

GET, POST

Dialplan rules

/api/dialplan_ib_route/

GET, POST

Inbound routes

/api/dialplan_ob_route/

GET, POST

Outbound routes

/api/dialplan_time_condition/

GET, POST

Time-based routing

Other

/api/clickdial/

POST

Click-to-dial functionality

/api/recordings/

GET, POST

Recording management

/api/callcentres/

GET, POST

Call center queues

/api/ringgroups/

GET, POST

Ring groups

/api/ivrmenus/

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

Extension Fields

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

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:

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

  1. Use verbose curl output: curl -v

  2. Check response headers for additional info

  3. Use API introspection endpoints when available

  4. Test with minimal required fields first

  5. 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.