Skip to main content

3CX

The 3CX integration imports call recordings from a 3CX phone system. It combines two 3CX features:

  • the Remote Archive, which stores recordings somewhere Speechlytics can read;
  • a CRM integration template, whose call-journaling step tells Speechlytics each time a call ends.

3CX cannot tell Speechlytics the recording's file name, so Speechlytics finds the recording in your archive by matching the reported call (agent extension or caller number, and call time) against the archive's file names.

1. Archive recordings​

Configure the 3CX Remote Archive to store recordings in a location Speechlytics can reach:

Recordings LocationExample
SFTPsftp://archive.example.com:22/var/lib/3cxpbx/Instance1/Data/Recordings
FTPftp://archive.example.com/Recordings
Network share or mounted folder\\fileserver\3cx\Recordings or /mnt/3cx/Recordings
  • Include the sftp:// or ftp:// prefix for SFTP and FTP. A value without a prefix is read as a folder on the Speechlytics server.
  • Point the location at the Recordings root, the folder that contains one subfolder per extension. Subfolders are read up to four levels deep.
  • Only .wav and .mp3 files are imported.
  • Keep 3CX's default file naming, for example [John Smith]_101-07700900123_20260928111812(42).wav. Speechlytics needs the date-time stamp (yyyyMMddHHmmss) and either the agent's extension or the other party's number in the file name.

Speechlytics only reads the archive. It copies recordings to its own storage and never modifies or deletes your files.

2. Configure the integration in Speechlytics​

Provide your Speechlytics representative with:

FieldMeaning
Recordings LocationThe archive location from step 1.
Archive Username / Archive PasswordCredentials for SFTP or FTP. Not needed for a share Speechlytics can already read.
Webhook SecretA secret you choose. Required: without it every call report is rejected.

Once saved, the integration shows its Webhook Url: https://<api-host>/api/v1/webhooks/threecx/<integration-id>.

3. Set up the CRM template in 3CX​

Create a 3CX CRM integration template with two scenarios, both pointing to the Webhook Url:

Contact lookup. A GET request with a JSON response type. 3CX requires a lookup scenario in every CRM template; Speechlytics holds no contacts and always answers {}.

Call journaling (ReportCall). A POST request with:

  • the secret in an x-3cx-signature header, or as Authorization: <secret> or Authorization: Bearer <secret>;
  • a JSON body with the call variables:
FieldRequiredMeaning
startTimeUtcOne of the two timesCall start (ISO 8601; read as UTC when no zone is given).
endTimeUtcOne of the two timesCall end.
agentagent or numberThe agent's extension.
numberagent or numberThe other party's number.
callTypeNoCalls reported as Missed or Notanswered are ignored.
callDirectionNoInbound or Outbound.
durationNomm:ss, hh:mm:ss or seconds. Measured from the audio when missing.
agentFirstName, agentLastNameNoThe agent's display name.

4. Switch the integration on​

Your representative switches the integration on once the Recordings Location and secret are saved.

How recordings are found​

When a call report arrives, Speechlytics:

  1. lists files written since shortly before the call started, first in the agent's extension folder (<root>/<extension>), then in the configured folder;
  2. picks the file whose time stamp is within two minutes of the call's start or end and whose name contains the agent's extension or the last seven digits of the other party's number. Time stamps in the phone system's local time zone are recognized;
  3. if no file is there yet, tries again several times over the next minute, because 3CX archives recordings after the call ends.

An hourly sweep also imports any new archive files that were never matched. Calls found only by the sweep have no agent, numbers or direction.

The recording's file name (without extension) is the call's External Id, so a recording is never imported twice. The agent is identified by display name or extension and created automatically if needed. The customer's name is not stored.

Troubleshooting​

SymptomWhat to check
Every call report is rejectedThe Webhook Secret is empty in Speechlytics, or the template sends a different value.
Calls arrive without agent or numbersThey were imported by the hourly sweep because the call report was not matched. Check that file names keep the time stamp and extension, and that the template sends agent, number and the call times.
Nothing is importedSpeechlytics cannot read the Recordings Location. Check the sftp:// or ftp:// prefix, host, path and credentials.
Only one extension's recordings are swept hourlyThe Recordings Location points at an extension folder; point it at the Recordings root.
Missed calls do not appearExpected: missed and unanswered calls are ignored.