RustPBX provides a comprehensive set of HTTP APIs and Webhooks designed to make it a fully programmable Software Defined PBX (SD-PBX). This guide details how to integrate your external business logic (CRM, ERP, AI assistants, billing systems) with RustPBX.
RustPBX interacts with external systems in two ways:
- Inbound API (REST): Your system calls RustPBX to manage resources (extensions, trunks) or control active calls.
- Outbound Webhooks: RustPBX calls your system to make routing decisions, report events, or authenticate users.
| Mechanism | Direction | Type | Use Case |
|---|---|---|---|
| Console API | Inbound | REST | CRUD extensions, download recordings, system config |
| Active Call Control | Inbound | REST | Live hangup, transfer, mute, force-accept |
| AMI API | Inbound | REST | Health checks, hot-reload, raw dialog inspection |
| HTTP Router | Outbound | Webhook | Dynamic call routing (per-INVITE decision) |
| User Backend | Outbound | Webhook | External SIP authentication (OAuth/LDAP proxy) |
| Locator Webhook | Outbound | Webhook | Real-time registration/unregistration events |
| Call Record Push | Outbound | Webhook | Push CDR JSON + Audio files to external server |
The most powerful extension point. Instead of static routing rules, RustPBX asks your API "Receive call from A to B, what should I do?".
- Trigger: Every incoming SIP INVITE.
- Config:
[proxy.http_router] url = "https://your-api.com/pbx/route" fallback_to_static = true # If your API fails, use internal routes timeout_ms = 5000 [proxy.http_router.headers] X-API-Key = "secret-token"
Request (POST):
{
"call_id": "ab39-551-229",
"from": "<sip:1001@pbx.com>",
"to": "<sip:200@pbx.com>",
"source_addr": "1.2.3.4:5060",
"direction": "inbound", // inbound | outbound | internal
"method": "INVITE",
"uri": "sip:200@pbx.com",
"headers": {
"User-Agent": "Yealink T54W",
"X-Client-ID": "998877"
},
"body": "v=0\r\n..." // Full SDP body
}Response:
{
"action": "forward", // Actions: forward | reject | abort | spam | not_handled
"targets": [
"sip:1001@192.168.1.50:5060", // Target 1 (Extension)
"sip:1002@192.168.1.51:5060" // Target 2 (Mobile App)
],
"strategy": "parallel", // parallel (Ring All) | sequential (Failover)
"record": true, // Enable recording for this call
"timeout": 30, // Ring timeout in seconds
"media_proxy": "auto", // auto | always | none | nat
"headers": { // Inject custom SIP headers into the INVITE sent to B
"X-Call-Reason": "support-ticket-123"
}
}Delegate SIP registration password checking to your external DB or API.
- Trigger: SIP REGISTER or INVITE with auth.
- Config:
[[proxy.user_backends]] type = "http" url = "https://your-api.com/pbx/auth" username_field = "u" realm_field = "r"
Request (GET): https://your-api.com/pbx/auth?u=1001&r=pbx.com
Response (200 OK):
{
"id": 1001,
"username": "1001",
"password": "hashed_password_or_plaintext", // HA1 hash preferred
"display_name": "John Doe",
"email": "john@pbx.com",
"allow_guest_calls": false
}Response (403 Forbidden):
{ "reason": "invalid_password", "message": "Account locked" }Real-time notification when devices come online or go offline.
- Config:
[proxy.locator_webhook] url = "https://your-api.com/pbx/events" events = ["registered", "unregistered", "offline"]
Payload:
{
"event": "registered",
"timestamp": 1708201234,
"location": {
"aor": "sip:1001@pbx.com",
"destination": "1.2.3.4:12345",
"transport": "TLS",
"user_agent": "MicroSIP/3.21.3",
"expires": 3600
}
}Push call details and recording file immediately after a call ends.
- Config:
[callrecord] type = "http" url = "https://your-api.com/pbx/cdr" with_media = true
Format: multipart/form-data
- Field
calllog.json: The full CDR JSON (see next section). - File
media_audio-0: The recording WAV/MP3 file.
Base URL: http://<rustpbx-ip>:8080/console
Authentication: Session cookie (login via /console/login) or API Token (future).
Manage calls that are currently in progress.
List Active Calls:
GET /console/calls/active
Control a Call:
POST /console/calls/active/{call_id}/commands
Payloads:
- Hangup:
{ "action": "hangup", "reason": "admin_kick" } - Blind Transfer:
{ "action": "transfer", "target": "sip:1002@pbx.com" } - Mute/Unmute:
{ "action": "mute", "track_id": "audio-0" } // use 'unmute' to reverse - Force Answer (for ringing channels):
{ "action": "accept", "sdp": "v=0..." // Server-generated SDP answer }
| Resource | Endpoint | Methods | Description |
|---|---|---|---|
| Extensions | /console/extensions |
GET, POST, PUT, DELETE |
Manage SIP users |
| Trunks | /console/sip-trunk |
GET, POST, PUT, DELETE |
Manage upstream carriers |
| Routes | /console/routing |
GET, POST, PUT, DELETE |
Manage dial plan rules |
| CDRs | /console/call-records |
GET, POST (Search) |
Query history |
| Recording | /console/call-records/{id}/recording |
GET |
Stream audio file |
| SIP Flow | /console/call-records/{id}/sip-flow |
GET |
Get PCAP-like ladder diagram JSON |
Low-level system operations. Protected by IP whitelist ([ami].allows in config).
Base URL: http://<rustpbx-ip>:8080/ami/v1
- Health:
GET /health- System vital stats (uptime, active calls, load). - Reload:
POST /reload/trunks,/reload/routes,/reload/acl- Hot reload config without restart. - Shutdown:
POST /shutdown- Graceful shutdown (stops accepting new calls, waits for active ones). - Dialogs:
GET /dialogs- Raw dump of internal SIP dialog states (for debugging). - SipFlow signaling:
GET /sipflow/flow/{call_id}- Query SIP ladder data. - SipFlow media:
GET /sipflow/media/{call_id}- Export call media as WAV.
SipFlow endpoints support optional time range query parameters:
start: range start timeend: range end time
Accepted formats:
- RFC3339 datetime, e.g.
2026-04-16T10:00:00+08:00 - Unix timestamp (seconds), e.g.
1713232800
Example:
GET /ami/v1/sipflow/flow/abc123?start=2026-04-16T10:00:00%2B08:00&end=2026-04-16T10:30:00%2B08:00
GET /ami/v1/sipflow/media/abc123?start=1713232800&end=1713234600- User clicks phone number in CRM.
- CRM backend sends
POST /api/v1/commands(Future feature) OR uses AMI to originate call. - Current workaround: CRM sends SIP REFER to RustPBX or uses a dedicated "Click-to-Dial" SIP extension that the web-app registers as.
- Inbound call hits RustPBX.
- HTTP Router sends INVITE details to AI backend.
- AI Backend returns
{"action": "forward", "targets": ["sip:ai-bot-service@internal"]}. - RustPBX routes audio to the AI bot via SIP/RTP.
- User Backend authenticates user, checking balance > 0.
- Call proceeds.
- On hangup, CDR Push sends via HTTP POST to Billing System.
- Billing system calculates duration * rate and deducts balance.
- Configure
[recording] enabled = true. - Configure
[callrecord] type = "s3". - All calls are recorded locally, then asynchronously uploaded to AWS S3 / MinIO for long-term archival.