Is it not enough 3CX CRM-Template? Use the 3CX REST API to integrate with any CRM or Service Desk system.


Use REST API to get IVR, Queue and Extension status of your 3CX

3CX Webhook generator

It generates events of the call passing through the PBX

3CX MP3 Records

Get a URL to download an mp3 records from your server 3CX

Windows & Debian

Use a build for Windows or Debian with the same functionality

Install as a Service

Install as a service (daemon) on your 3CX server and use.

Make call

Use the URL request to make an outgoing call

Phone system integration

You’ll get:

3CX REST API Pricing

REST API and Webhook generator

up to 32 concurrent calls

MP3 Records
Webhook Generator
Tech Support
Windows & Debian

32-128 concurrent calls

1 950/year
MP3 Records
Webhook Generator
Tech Support
Windows & Debian

128+ concurrent calls

3 950/year
MP3 Records
Webhook Generator
Tech Support
Windows & Debian

Technical Descriptions

The “webhooks” module is used to integrate 3CX with third-party CRM systems. It is written in C #, implemented as a service and connects to 3CX at the time of start. As a result, the module continuously monitors the low-level telephone exchange activity and on this basis of monitoring generates a high-level events occur:

  • ringing
  • call start
  • call end

3CX Webhook generator sends  at the moment of each of the events https-request (webhook) on the address specified in the .ini file with certain data about the call.

Note: if an extension’s phone rang, and then stopped ringing, but the call did not end (went to another extension), then there is no such event (the extension’s phone stopped ringing, but the call did not end).

Description of the data that is transmitted via webhooks when events occur

The phone rings at such and such extension number

  • event = ringing
  • callerid = Caller ID
  • did = external number the call was received from (incoming DID rule)
  • user = user extension 
  • usertype = ext/queue/other
  • id = unique call id (string value). If a call has come to the queue and the phone is sequentially or simultaneously ringing for several managers, then they will all have the same id.

Call started

  • event = hangupincoming / hangupoutgoing (Incoming or outgoing call)
  • callerid = External number participating in the conversationExtension
  • user =participating in the conversation
  • did = If the call is incoming, then the external number that received the call (DID- rule)
  • trtype = NotDef / Blind / Accomp (How the call was received: 1) a regular call, 2) a call received through a blind transfer, 3) a call received through an accompanying transfer)
  • Id = Unique call id (string value) The

Call ended

  • event = incoming / outgoing
  • callerid = External number
  • user = Internal number. If the call is missed, and it ended at the queue level, then this will be the queue extension
  • finishtype = Ok / Missed (How the call ended: successful (there was a conversation) or unsuccessful (i.e. when an outgoing call was called, but the other end did not picked up the phone, and when the call came in, no one answered the call on the 3CX side))
  • transfer = false / true (Did the call end completely, or went through the transfer to another extension)
  • title = As a phrase, detailed information about the call, which, in addition to the above includes: a) the name of the DID rule for an incoming call; b) if the call ended at the queue level, was a callback ordered; c) call duration
  • id = Unique call id (string value) The

call ID is formed as follows:

[date time]_[unique call number within the current 3CX session]-[call link number]

Example ID: 210701165649_698-2

Date and time correspond to the moment when the call arrived at the 3CX. A call link is a sequence number of a call in a single chain of transfers. When a call has just arrived at the PBX, and no one has answered it yet, the call link is equal to 0. As soon as someone answers, it is equal to 1. For each subsequent transfer, the call link is increased by 1. All calls in a single transfer chain have a date time and a unique number within the current session are the same. Such calls differ only in the link number.



After the complete end of the call (when the external subscriber hangs up), a recording of the conversation appears in 3CX, or several recordings of conversations that correspond to the entire chain of transfers, if any. Recordings of conversations appear with a slight delay: from a few milliseconds to 1-2 seconds after hanging up. As soon as this happens, the “webhooks” module converts the wav-file (s) with the recording (recordings) into mp3-format and places them in a separate folder, from which it is possible to download recordings via an https-link. The link to download the files is sent via the corresponding POST request. Thus, a webhook with information about the end of the call and a webhook with a link to the conversation file are different, separate webhooks.

In a POST request, in the general case, several links can be sent to download a conversation recording. The fact is that in 3CX one conversation can correspond to several sound files. This happens if they spoke through a mobile application, and during the conversation, the connection was lost for a short time. In this case, each short-term disconnection is the beginning of a new record file.

In addition to the link to the conversation record, the POST request contains a call id, by which it can be identified with the call start / end events. Optionally (via an ini file) in the POST request, you can enable the transfer of complete information about the ended call. In this case, the POST request will contain the same information (besides the link to download the record) as the call termination event.

Records of conversations in mp3 format are stored in a separate package for the required number of days (the corresponding parameter is set in the ini-file of the service). At night, records that have expired are automatically deleted by the service.



List of GET requests for the 3CX REST API

Get the current number of calls passing through the PBX

Get detailed information about all currently active connections


  • count – total number of active connections (calls passing through the PBX)
    AConnByCallID – list of active connections:
  • CallID – Call ID
    direction – the direction of the call. Possible values:
  • FromExternal – the call came from an external line, but it hasn’t been distributed yet
  • FromInternal – the call came from an internal number, but it hasn’t been distributed yet
  • Inbound-call from an external line to an internal number
  • Outbound-call from an internal number to an external line
  • External-call from an external line to an external line
  • Internal-call from an internal number to an internal one
  • Did – DID rule

Get detailed information about all current calls. The information is essentially similar to that provided by the previous pbx.calls.get?key={secret key} command, but the information is provided in a slightly different cross-section and logic.


  • count – total number of calls
    callsInfo – list of calls currently passing through the PBX
  • CallID – Call ID
    state – call state: Unknown, Initiating, Routing, Talking, Transferring, Rerouting
     – call start time answeredAt – call
     time (can be null)
    did – for a call from an external line, the name of the DID rule, if any
     – information about the owner of the call. Matches data from the OMCallCollector class.ActiveConnectionFields
    talkTo – information about who the owner of the call is talking to (if he is talking), and a list. Matches data from the OMCallCollector class.ActiveConnectionFields
    routingTo – information about who the call is being sent to (if any), and a list. Matches data from the OMCallCollector class.ActiveConnectionFields

Get a list of all user extensions

Get a list of all registered user extensions

Get a list of all call groups

Get a list of all call queues

Get a list of all IVRs

Get a list of all external lines (paths)

Get user extension information fields
ext.info.get?num={extension number}

Get user Extension number statuses
ext.state.get?num={extension number}


  • num – the user’s extension number
    registered – whether or not this extension is registered on the PBX
    status – Free-the subscriber is not in conversation, Busy-the subscriber is in conversation or receives a call or makes a call
    fwdName – current redirect status
    qGlobalStatus – global entry/exit status of all queues
    qStatus – entry/exit statuses for specific queues (num – queue number, status – status)

Get a list of all queue operators
queue.members.get?num={queue number}

Get a list of all available queue operators
queue.free.get?num={queue number}

Get a list of all queue operators that are in conversation
queue.talk.get?num={queue number}

Find out if there is at least one free queue operator ready to receive the call
queue.isfree.get?num={queue number}

Get a list of all call group statements
group.members.get?num={call group number}

Get a list of all available call group operators
group.free.get?num={call group number}

Make a call
makecall?first={first call shoulder number}&second={second call shoulder number}

Change the forwarding status of the user’s extension number
ext.fwd.set?num={extension number}&status={name of the forwarding status in english}

answer: the command execution was completed successfully/unsuccessfully, the command fails if incorrect data (user extension number and/or status name) is transmitted.

Set the option of global entry/exit from all queues for the user’s extension number
ext.queueglobal.set?num={extension number}&log={on/off}

answer: the command was executed successfully/unsuccessfully
If forwarding statuses are responsible for global entry/exit from queues, the result is false – no entry/exit from queues will occur. In this case, use changing the forwarding status.

Enter / output a queue operator to a specific queue
ext.queue.set?num={extension number}&queue={queue number}&log={on/off}

answer: the command was executed successfully/unsuccessfully. The command fails if incorrect data (user extension number and/or queue number)is transmitted

Set options for the user’s extension number
ext.options.set?num={extension number}&enabled={on/off}&external={on/off} &recording={off/external/all}

When using a command, you can use only one or two options, rather than all 3 options.

Value of options:
enabled – the extension number is enabled or disabled
external – whether calls to external numbers are allowed
recording-call recording mode (disabled/external calls only/all calls)

Integration success story 3CX API