https://<your-domain>/api, for example https://demo.ictpbx.com/apiX-API-Key header. See Authentication.GET /tenants means GET https://<your-domain>/api/tenants.GETPOSTPUTDELETE
Log in for a JWT, or use an API key
Authenticate once to obtain a signed JWT, then send it as a Bearer token on every subsequent request. The token payload carries the user identity, tenant, permissions, and credit balance (Service Provider Edition). It is signed RS256 and validated server-side, so never modify it.
You can use an API key instead of a JWT. Create one under Administration → API Keys and send it in the X-API-Key header. A key acts with the permissions of the user it belongs to. It’s rate-limited, so you’ll get a 429 if you go over the limit, and you can’t use a key to create other keys.
POST /authenticate
Content-Type: application/json
{ "username": "admin@example.com", "password": "<your password>" }
Authorization: Bearer <jwt>
# or, with an API key:
X-API-Key: <your key>
Sessions & password
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /authenticate |
Log in, returns a JWT |
| POST | /authenticate/cancel/$user_id |
Invalidate / cancel a user session |
| POST | /forgot_password |
Trigger a password-reset email |
| PUT | /update_password |
Complete a password reset (token from email) |
| POST | /token_payload |
Decode / inspect a token payload |
| GET | /get_user |
Current authenticated user |
Multi-factor (TOTP)
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /user/totpqrcode |
Generate the TOTP enrolment QR code |
| POST | /user/totp/verify |
Verify a TOTP code to complete MFA |
Shapes, identifiers, headers, errors, scoping
3.1 Standard REST shape
Most resources follow the same pattern (shown here for tenants):
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /tenants |
List |
| GET | /tenants/$tenant_id |
Read one |
| POST | /tenants |
Create |
| PUT | /tenants/$tenant_id |
Update |
| DELETE | /tenants/$tenant_id |
Delete |
3.2 Identifiers
Core resources (tenant, user, provider, route, account, document…) use numeric IDs. PBX resources (extensions, devices, ring groups, IVR menus, voicemail, conferences, etc.) use UUIDs ($..._uuid).
3.3 Headers
Authorization: Bearer <jwt> # or X-API-Key: <your key>
Content-Type: application/json
Accept: application/json
3.4 Error format
Errors return an HTTP status and a JSON envelope:
{ "error": { "code": 404, "message": "Document media not found" } }
Common codes: 401 invalid/expired token, 403 not permitted (wrong role/permission), 404 not found, 409 conflict (e.g. extension already in use), 423/429 login lockout.
3.5 Permission scoping
- Admin sees and manages all tenants.
- Tenant admin is scoped to their own tenant; list endpoints auto-filter by tenant.
- End users are limited to their own objects (My Account, own fax, own quota).
- PBX write operations (create/update/delete) require an admin or tenant-admin role.
3.6 CSV export / import
Many list resources offer companion CSV routes, e.g. GET /cdr/csv, GET /routes/csv, GET /groups/$group_id/csv, POST /contact_dncs/import/csv.
Tenants, users, roles, branding
4.1 Tenants (Service Provider Edition)
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /tenants |
List organisations |
| GET | /tenants/$tenant_id |
Tenant detail (includes tenant_permissions) |
| POST | /tenants |
Create tenant (auto-provisions a FreeSWITCH domain) |
| PUT | /tenants/$tenant_id |
Update, including max_concurrent_calls, credit_alert_threshold |
| DELETE | /tenants/$tenant_id |
Delete (cascades PBX + DID cleanup) |
4.2 Users
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /users/users/$user_id |
List / read users |
| POST | /users |
Create user (password, role, permissions) |
| PUT | /users/$user_id |
Update user |
| DELETE | /users/$user_id |
Delete user |
| GETPUT | /users/$user_id/permissions/permissions/$permission_id |
Read / grant / revoke permissions |
| GETPUTDELETE | /users/$user_id/roles/roles/$role_id |
Manage user roles |
| PUT | /users/$user_id/password |
Change password |
| GETPUT | /users/$user_id/config/$config_name |
Per-user config (e.g. forwarding / DND) |
| GET | /users/$user_id/accounts |
Accounts owned by the user. Add ?type=did to list just their DIDs. |
| GET | /users/$user_id/status/token |
Status / impersonation token |
| GET | /users/activities/$user_id/activity/$user_id |
Activity log |
| GET | /users/act/csv/$userid |
Activity CSV export |
4.3 Roles & permissions
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /roles/roles/$role_id |
List / read roles |
| POSTPUTDELETE | /roles/roles/$role_id |
Manage roles |
| PUTDELETE | /roles/$role_id/permissions/$permission_id |
Attach / detach permission |
| GETPOST | /permissions |
List / define permissions |
4.4 Branding (Service Provider Edition) & system settings
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /branding/$tenant_id |
Branding for a tenant (auth) |
| GET | /branding/$tenant_id/media |
Logo bytes |
| PUT | /branding/$tenant_id/media |
Upload logo |
| POST | /branding |
Save branding |
| GET | /branding_public/$host |
Public branding for login page (no auth) |
| GET | /branding_default |
Default theme |
| GETPOST | /announcement/announcement/$tenant_id |
System announcements |
| GETPOST | /password_policy |
Read / set password policy |
Trunks (providers), routes and DIDs
| Method | Endpoint | Purpose |
|---|---|---|
| GETPOSTPUTDELETE | /providers/providers/$provider_id |
SIP trunks (providers). In the portal these are Routing → Trunks, and only a Super Admin can manage them. Filter fax-capable: GET /providers?service_flag=2 |
| GET | status/providers |
Trunk registration status |
| GETPOSTPUTDELETE | /routes/routes/$route_id |
Outbound routes |
| POST | /routes/bulk |
Bulk route create |
| GETPOST | /routes/csv/routes/sample/csv/routes/$service_flag/$provider_id/csv |
Route CSV import / export |
| GETPOSTPUTDELETE | /dids/dids/$account_id |
DID numbers |
| PUT | /dids/$account_id/assign |
Assign a DID to a tenant / account |
| GETPOST | /cids |
Caller-ID (CID) numbers |
| GET | /gateways/gateways/$gateway_uuid |
A read-only view of your trunks. To add or change a trunk, use /providers. |
| GETPOSTPUTDELETE | /destination/destination/$destination_id |
Routing destinations |
Extensions, devices, call handling, realtime
6.1 Extensions
| Method | Endpoint | Purpose |
|---|---|---|
| GETPOSTPUTDELETE | /fpbx_extensions/fpbx_extensions/$extension_uuid |
Extensions |
| GET | /fpbx_extensions/next_available |
Suggest next free extension number |
| GET | /fpbx_extensions/check |
Conflict check across all extension tables |
| GET | /fpbx_extensions/available_for_fax |
Extensions usable as fax endpoints |
| POST | /fpbx_extensions/$extension_uuid/assign |
Assign an extension to a user |
| GET | /fpbx_domains/fpbx_domains/$tenant_id |
Tenant → FreeSWITCH domain |
6.2 Devices & auto-provisioning
| Method | Endpoint | Purpose |
|---|---|---|
| GETPOSTPUTDELETE | /devices/devices/$device_uuid |
Devices (MAC normalised on save) |
| GETPOSTPUTDELETE | /device_profiles/device_profiles/$device_profile_uuid |
Shared config profiles |
| GETPOSTPUTDELETE | /device_lines/device_lines/$device_line_uuid |
SIP lines on a device |
| GET | /device_vendors |
Supported vendors / models |
/provision/{mac} alias, not an /api route.6.3 Call-handling modules
| Method | Endpoint | Purpose |
|---|---|---|
| GETPOSTPUTDELETE | /ring_groups/ring_groups/$ring_group_uuid |
Ring groups |
| GETPOSTPUTDELETE | /call_queues/call_queues/$call_center_queue_uuid |
Call queues |
| GETPOSTPUTDELETE | /ivr_menus/ivr_menus/$ivr_menu_uuid |
IVR menus |
| GETPOSTPUTDELETE | /voicemails/voicemails/$voicemail_uuid |
Voicemail boxes |
| GETPOSTDELETE | /voicemail_greetings/voicemail_greetings/$greeting_uuid |
Greeting upload / delete |
| GETPOSTPUTDELETE | /conferences/conferences/$conference_center_uuid |
Conference rooms |
| GETPOST | /conference_participants |
Live participant control (mute / kick) |
| GETPOSTPUTDELETE | /time_conditions/time_conditions/$dialplan_uuid |
Time conditions |
| GETPOSTPUTDELETE | /call_flows/call_flows/$call_flow_uuid |
Call flows (toggles) |
| GETPOSTPUTDELETE | /call_block/call_block/$call_block_uuid |
Inbound call blocking |
| GETPOSTPUTDELETE | /follow_me/follow_me/$follow_me_uuid |
Follow-me forwarding |
| GETPOSTPUTDELETE | /music_on_hold/music_on_hold/$music_on_hold_uuid |
Music on hold |
| GETPOSTPUTDELETE | /inbound_routes/inbound_routes/$destination_uuid |
DID → destination routing |
| GET | /feature_codes |
Read-only feature-code list. Only *99 (AI Voice Agent, when installed) and *99 plus a mailbox number (voicemail, e.g. *991001) actually work. |
| GET | /dialplans |
Raw dialplan entries |
6.4 Realtime monitoring & call control
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /realtime |
Active channels + registrations (polled) |
| POST | /realtime/control |
Control a live call: hangup / hold / transfer |
| POST | /call/originate |
Click-to-call. Rings from_ext first, then dials to_number. |
POST /call/originate
{ "from_ext": "1001", "to_number": "+12015550123" }
# response
{ "status": "queued", "job_uuid": "..." }
Extension 1001 rings first. When it answers, ICTPBX places the call to to_number. The API answers straight away with a job_uuid. If from_ext isn’t registered right now, you’ll get a 409 instead.
Send, campaigns, documents, contacts, accounts
7.1 Sending faxes (programs → transmissions)
| Method | Endpoint | Purpose |
|---|---|---|
| GETPOST | /programs/programs/$program_name |
Service programs (fax / voice templates) |
| POST | /programs/$program_name/transmissions |
Launch a transmission (send a fax) |
| GETPUTDELETE | /transmissions/transmissions/$transmission_id |
Transmission records |
| POST | /transmissions/$transmission_id/send/retry |
Send / retry |
| GET | /transmissions/$transmission_id/status/result/logs/detail |
Status & results |
| GETPUTDELETE | /transmissions/$transmission_id/schedule |
Scheduling |
7.2 Campaigns (bulk fax)
| Method | Endpoint | Purpose |
|---|---|---|
| GETPOSTPUTDELETE | /campaigns/campaigns/$campaign_id |
Campaigns |
| GETPUT | /campaigns/$campaign_id/start/stop |
Start / stop |
| POSTPUTDELETE | /campaigns/$campaign_id/$action/schedule |
Scheduling |
7.3 Documents, media & received faxes
| Method | Endpoint | Purpose |
|---|---|---|
| GETPOSTPUTDELETE | /documents/documents/$document_id |
Fax documents |
| POSTPUT | /documents/$document_id/media |
Upload document file |
| GET | /documents/$document_id/media/$user_id/media/media/$transmission_id |
Download (decrypts AES → PDF) |
| GET | /faxes/calls |
Per-channel message lists |
| GETPOSTPUTDELETE | /coverpages/coverpage/$coverpage_id |
Fax cover pages |
7.4 Contacts, groups & DNC
| Method | Endpoint | Purpose |
|---|---|---|
| GETPOSTPUTDELETE | /contacts/contacts/$contact_id |
Contacts |
| PUTDELETE | /contacts/$contact_id/link/$group_id |
Add / remove contact ↔ group |
| GETPOSTPUTDELETE | /groups/groups/$group_id |
Contact groups |
| GET | /groups/$group_id/contacts/csv/sample/csv |
Group members / CSV |
| GETPOSTPUTDELETE | /contact_dncs/contact_dncs/$contact_dnc_id |
Do-Not-Contact list |
| POST | /contact_dncs/import/csv |
DNC import |
7.5 Recordings & templates (the /messages namespace)
| Method | Endpoint | Purpose |
|---|---|---|
| GETPOSTPUTDELETE | /recordings/messages/recordings |
Audio recordings (+ /media) |
| GETPOSTPUTDELETE | /templates/messages/templates |
Reusable templates (+ /media) |
| GETPOSTPUTDELETE | /messages/documents |
Message-scoped documents (+ /media) |
7.6 Accounts
There’s no Fax Accounts menu any more. A fax line is an extension with its Extension Type set to Fax, so you create it through /fpbx_extensions. The routes below work on the account records ICTCore keeps behind the scenes, such as DIDs.
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /accounts/accounts/my |
All accounts, or just your own |
| GETPOSTPUTDELETE | /accounts/accounts/$account_id |
Manage accounts |
| GET | /accounts/$account_id/provisioning |
Provisioning detail |
| GETPUTDELETE | /accounts/$account_id/settings/$name |
Per-account settings |
| GET | /accounts/linkdid/$account_id |
Linked DID |
Call records, spools, statistics
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /cdr/cdr/list |
ICTCore call records (fax / voice) |
| GET | /cdr/csv |
CDR CSV export |
| GET | /usersCDR/usersCDR/csv |
Per-user / extension CDR |
| GET | /fpbx_cdr |
FreeSWITCH PBX call records |
| GETPOST | /cdr_etl/status/cdr_etl/run |
Trigger / poll the CDR ETL job |
| GET | /spools/spools/$spool_id/status/result/results |
Spool (job) status |
| GET | /spools/csv/spoolsstat/spools/stat |
Spool stats |
| GET | /stat/stat/csv/statistics/pbx_statistics |
Dashboard statistics |
Quota, packages, subscriptions, payments (Enterprise)
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /billing/quota |
Current tenant slot + usage quota |
| GET | /billing/quota/all/$tenant_id |
Full quota detail for a tenant |
| PUT | /billing/quota/$tenant_id |
Set quota limits |
| GET | /billing/usage |
Usage breakdown for the period |
| GET | /billing/credit |
Process new CDRs and return current credit |
| GET | /billing/gate |
Billing feature gate (edition check) |
| GETPOSTPUTDELETE | /packages/packages/$id |
Resource packages (super-admin) |
| GETPOST | /subscriptions |
Tenant ↔ package assignment |
| GET | /subscriptions/packages |
Package list for dropdown |
| PUT | /subscriptions/$id/activate/suspend |
Activate / suspend subscription |
| GETPOSTPUTDELETE | /rates/rates/$rate_id |
Per-unit rates (+ CSV routes) |
| GETPOSTPUTDELETE | /plans/plans/$plan_id |
Pricing plans |
| GETPOSTPUTDELETE | /payments/payments/$payment_id |
Top up a tenant’s credit. Credit is held per tenant, not per user. |
Countries, regions, timezones, services
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /country/country/$country_id |
Country list |
| GET | /region/region/$region_id |
Regions |
| GET | /timezone/timezone/$timezone_id |
Timezones |
| GET | /services |
Service catalogue (voice / fax flags) |
| GET | /permissions |
Permission catalogue |
Copy-paste curl recipes
Log in and store the token
TOKEN=$(curl -s -X POST https://demo.ictpbx.com/api/authenticate \
-H 'Content-Type: application/json' \
-d '{"username":"admin@example.com","password":"<your password>"}' \
| sed -E 's/.*"token":"([^"]+)".*/\1/')
List resources
curl -s https://demo.ictpbx.com/api/tenants \
-H "Authorization: Bearer $TOKEN" -H 'Accept: application/json'
Create an extension
curl -s -X POST https://demo.ictpbx.com/api/fpbx_extensions \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"extension":"1005","password":"S3cret!","display_name":"Reception"}'
Update a tenant’s fraud limit
curl -s -X PUT https://demo.ictpbx.com/api/tenants/85 \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"max_concurrent_calls":10,"credit_alert_threshold":5}'
Click-to-Call
curl -s -X POST https://demo.ictpbx.com/api/call/originate \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"from_ext":"1001","to_number":"+12015550123"}'
Delete a device
curl -s -X DELETE https://demo.ictpbx.com/api/devices/<device_uuid> \
-H "Authorization: Bearer $TOKEN"
Community vs Enterprise
- Community Edition does not expose the Billing section. Calls to those endpoints are gated and return empty / forbidden results.
- CE is single-tenant: tenant-management endpoints exist but the system operates with one organisation.
- All other sections (Authentication, Administration basics, Routing, PBX, Fax, CDR, Reference) are identical across editions.
Building an integration on ICTPBX? Spin up the API on your own server.
Using the API from AI tools and code
You do not have to hand-write every call above. Three open source packages sit on top of this API. The ICTPBX MCP server gives an AI assistant a read-only view of extensions, DIDs, trunks and tenants. The LangChain tools expose the same queries to agent frameworks. And pbx-mcp goes one layer down, letting an assistant inspect the Asterisk or FreeSWITCH engine directly. All three are MIT licensed. If you are new to the platform, start with the getting started guide before wiring anything up.