Skip to main content

Download Call Recordings & Transcriptions

· 5 min read
Vadim Ruban
Software Engineer

In this guide, we will explore the various options for downloading call audio recordings & transcriptions from the Wildix system. To successfully implement these features, you'll need to understand two different authorization methods:

  1. Simple Token - Used for downloading audio recordings directly from the PBX
  2. Cloud Token - Required for accessing transcriptions from cloud services

Simple Token

Simple token authorization allows your service to make requests to the PBX on behalf of a specific user.

How to create a Simple Token:

  1. Go to WMS -> PBX -> Integrations -> Applications
  2. Click Simple Token
  3. Click Add to add a new token and select the user on whose behalf you want to make requests (select admin if you need access to all recordings in the system)
  4. Click Save and copy the secret key to a secure location for use in your service

Cloud Token

Cloud API Token is used specifically for cloud services and cannot be used directly with the PBX. This token allows you to download transcriptions and AI summaries.

How to get Cloud Token Credentials:

  1. Go to WMS
  2. Open the Terminal in the top right corner (URL should be similar to https://example.wildixin.com/terminal/)
  3. Enter the following command to retrieve the PBX secret key and serial number:
cat /rw2/etc/sf2 | head -18 | tail -2 | xargs printf "pbxSerial: %s\npbxKey: %s\n"
  1. Use this serial and secret key with the PbxTokenProvider for authorization when accessing cloud services

Configuring Webhooks

To receive notifications about call events, you need to set up webhooks in the system:

  1. Go to WMS -> PBX -> Integrations -> Cloud integrations
  2. Click Webhooks
  3. Click Add new integration to create a new integration or edit an existing one
  4. Select Analytics events -> call:completed
  5. Click Save

Once configured, the system will send webhook notifications containing call flows (segments of the conversation) with an attachments array when a call is recorded.

Example webhook payload:

{
"id": "it_w119414_1741864367.75",
"type": "call:completed",
/* ... other fields ... */
"data": {
/* ... other fields ... */
"flows": [
{
/* ... other fields ... */
"attachments": [
{
"recording": {
"url": "https://example.wildixin.com:443/spoolview/recordings/2025.03.13/11/33/2025.03.13-11.33.30-321313-bot111[pbx]-ef607-0.wav",
"fileName": "2025.03.13-11.33.30-321313-bot111[pbx]-ef607-0.wav",
"start": 1741862010663,
"end": 1741862034257,
"pauses": [],
"owner": "system"
}
}
]
}
]
}
}

Download Audio Recording

Audio recordings can be downloaded using the Simple Token you configured on the PBX. When implementing the download functionality, it's important to allow redirects as the download URL may redirect to a cloud storage location. If a recording was just created, no redirect will occur.

import fs from 'fs';
import {mkdir} from 'fs/promises';
import path from 'path';

(async () => {
console.log('Start');

const url =
'https://example.wildixin.com:443/spoolview/recordings/2025.03.13/11/33/2025.03.13-11.33.30-321313-bot111[pbx]-ef607-0.wav';
const fileName = url.split('/').pop() || 'recording.wav';
const recordingsDir = path.join(__dirname, 'recordings');

// Create recordings directory if it doesn't exist
await mkdir(recordingsDir, {recursive: true});

const response = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer %PBX_SIMPLE_TOKEN%`,
},
});

const buffer = Buffer.from(await response.arrayBuffer());

// Save the file
await fs.promises.writeFile(path.join(recordingsDir, fileName), buffer);

console.log(`File saved as: recordings/${fileName}`);

console.log('End');
})();

Download Transcription

After a call ends, the system stores the transcription on the configured cloud storage with a specified retention period. Transcriptions are typically available after the call:completed event is triggered.

To handle potential race conditions where the call:completed webhook is sent before the transcription is ready, you should implement a retry mechanism in your code. Adding 3 retry attempts when querying the API will help avoid these issues.

import {PbxTokenProvider} from '@wildix/auth-utils';
import {
CallNotFoundException,
CallTranscriptionNotFoundException,
GetCallTranscriptionCommand,
WdaHistoryClient,
} from '@wildix/wda-history-client';

import retry from 'async-retry';

(async () => {
console.log('Start');

const token = new PbxTokenProvider('PBX_CLIENT_ID', 'PBX_CLIENT_SECRET');
const client = new WdaHistoryClient({token});

const callId = '...';
const flowIndex = 0;

// Try to get call details in 3 attempts, because the event processing pipeline takes time.
const callTranscriptionResponse = await retry(
async (bail) => {
try {
return await client.send(new GetCallTranscriptionCommand({callId, flowIndex}));
} catch (error) {
if (!(error instanceof CallNotFoundException || error instanceof CallTranscriptionNotFoundException)) {
bail(error);
}

throw error;
}
},
{retries: 3},
);
const {transcription} = callTranscriptionResponse;

console.log('Transcription', JSON.stringify(transcription));

console.log('End');
})();

Webhook-Based Transcription Retrieval

Alternatively, your server can subscribe to the call:transcription:completed webhook event. The system will send the transcription information as soon as it's ready, typically within a second after the call:completed event.

Example webhook payload for transcription:

{
"id": "it_w119414_1741864367.75",
"type": "call:transcription:completed",
/* ... other fields ... */
"data": {
"call": {
/* ... other fields ... */
},
"chunks": [
{
"id": "d578a74d-b54d-4f7b-b883-0d1b33e50606",
"name": "Vadim",
"offset": 2296,
"text": "Hello, how are you?",
"time": "00:00:02"
}
/* ... other chunks ... */
]
}
}

If you need formatted text rather than chunks, you can use the call:transcription:text:completed event, which includes formatted text information.