Video API Reference

View Release Notes →

The EnableX Video API is a server-side REST API. Your application server calls it to provision rooms, issue join tokens, and retrieve post-session data. Client endpoints (browsers, mobile apps) never call this API directly — they receive a token from your server and use it with the Video SDK to join a session.

Authentication & Base URL

All requests to the Video API use HTTP Basic Authentication. Your credentials are the APP_ID (username) and APP_KEY (password) from your EnableX project. Encode them as a Base64 string in the format APP_ID:APP_KEY and pass it in every request header.

Authorization: Basic <base64(APP_ID:APP_KEY)>

The base URL for all Video API v2 endpoints is:

https://api.enablex.io/video/v2/

Append the route path for each endpoint. For example, the rooms endpoint is:

https://api.enablex.io/video/v2/rooms
Getting Your APP_ID and APP_KEY
  • Log in to the EnableX Portal and create or open a project.
  • Enable the Video capability on the project.
  • In the project settings, click Send App Credentials — your APP_ID and APP_KEY will be emailed to your registered address.
  • Keep your APP_KEY secret. Never embed it in client-side code or expose it in a browser.

Common Request Headers

HeaderRequiredValue
AuthorizationAlwaysBasic <base64(APP_ID:APP_KEY)>
Content-TypePOST / PATCH onlyapplication/json

Response Envelope

Every API response is a JSON object. A successful response always contains "result": 0. Any non-zero value indicates an error, accompanied by an "error" field describing the problem.

Try It Live — Open API Tool

EnableX provides an interactive API explorer (similar to Postman) where you can test every endpoint directly in your browser without writing any code. Open the API Tool →

Endpoint Index

All endpoints are relative to https://api.enablex.io/video/v2.

MethodEndpointWhat it does
POST/roomsCreate a room
GET/roomsList all rooms
GET/rooms/{room_id}Get room details
PATCH/rooms/{room_id}Update a room
DELETE/rooms/{room_id}Delete a room
POST/rooms/{room_id}/tokensCreate a join token
GET/rooms/{room_id}/usersGet active users in session
GET/archive/conf/{conf_num}Archive by conference number
GET/archive/room/{room_id}Archive by room
GET/archive/room-period/{room_id}/{from}/{to}Archive by room & date range
GET/archive/period/{from}/{to}Archive across all rooms by date
GET/cdr/conf/{conf_num}CDR by conference number
GET/cdr/room/{room_id}CDR by room
GET/cdr/room-period/{room_id}/{from}/{to}CDR by room & date range
GET/cdr/period/{from}/{to}CDR across all rooms by date
GET/dialin/Get dial-in phone numbers
Room Management

Room Types & Modes

A Room is the virtual meeting space on the EnableX platform. You define its settings once through the API, and the platform enforces them for every session that takes place inside it. Rooms are created ahead of time by your application server — they are not created by end-users.

Room Types

Choose the room type that matches your use case:

  • Permanent Room — Always available. Supports unlimited sessions over its lifetime. Use this for recurring meetings, support desks, or always-on collaboration spaces.
  • Scheduled Room — Opens 15 minutes before its scheduled start time and remains available for its defined duration. Tokens cannot be issued outside this window. Use this for webinars, appointments, or time-boxed events.
  • Adhoc Room — Available for a single session by default; once used, it is deleted. If a duration is specified, it remains available for multiple sessions until that duration elapses from the first session's start time. Use this for on-demand calls.

Session Modes

  • Group Mode — All moderators and participants can see and hear each other. This is the default mode for standard video calls and conferences.
  • Lecture Mode — Designed for webinars and presentations. Only moderators publish audio and video. Participants can see and hear moderators but cannot publish unless a moderator explicitly grants permission.

Create a Room

Creating a room registers it on the EnableX platform and returns a room_id. This room_id is used for all subsequent operations: updating room settings, issuing tokens, fetching reports, and more. Creating a room does not start a session — sessions begin when the first participant connects with a valid token.

POST https://api.enablex.io/video/v2/rooms
Authorization: Basic <base64(APP_ID:APP_KEY)>
Content-Type: application/json

Request Body

curl -X POST https://api.enablex.io/video/v2/rooms \
  -u YOUR_APP_ID:YOUR_APP_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekly Team Standup",
    "owner_ref": "user_8821",
    "settings": {
      "description": "Daily 15-minute standup for the product team",
      "mode": "group",
      "scheduled": false,
      "adhoc": false,
      "duration": 30,
      "moderators": "1",
      "participants": "10",
      "quality": "HD",
      "auto_recording": false,
      "screen_share": true,
      "canvas": false,
      "knock": false,
      "wait_for_moderator": false,
      "abwd": true,
      "max_active_talkers": 4,
      "media_zone": "XX",
      "single_file_recording": false,
      "role_based_recording": {
        "moderator": "audiovideo",
        "participant": "audio"
      }
    },
    "sip": { "enabled": false },
    "data": { "your_custom_key": "any value you need" }
  }'  
const axios = require('axios');

const response = await axios.post(
  'https://api.enablex.io/video/v2/rooms',
  {
    name: 'Weekly Team Standup',
    owner_ref: 'user_8821',
    settings: {
      description: 'Daily 15-minute standup for the product team',
      mode: 'group',
      scheduled: false,
      adhoc: false,
      duration: 30,
      moderators: '1',
      participants: '10',
      quality: 'HD',
      auto_recording: false,
      screen_share: true,
      canvas: false,
      knock: false,
      wait_for_moderator: false,
      abwd: true,
      max_active_talkers: 4,
      media_zone: 'XX',
      single_file_recording: false,
      role_based_recording: {
        moderator: 'audiovideo',
        participant: 'audio'
      }
    },
    sip: { enabled: false },
    data: { your_custom_key: 'any value you need' }
  },
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

// room_id is in response.data.room.room_id — store it for later use
console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

response = requests.post(
    'https://api.enablex.io/video/v2/rooms',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY'),
    json={
        'name': 'Weekly Team Standup',
        'owner_ref': 'user_8821',
        'settings': {
            'description': 'Daily 15-minute standup for the product team',
            'mode': 'group',
            'scheduled': False,
            'adhoc': False,
            'duration': 30,
            'moderators': '1',
            'participants': '10',
            'quality': 'HD',
            'auto_recording': False,
            'screen_share': True,
            'canvas': False,
            'knock': False,
            'wait_for_moderator': False,
            'abwd': True,
            'max_active_talkers': 4,
            'media_zone': 'XX',
            'single_file_recording': False,
            'role_based_recording': {
                'moderator': 'audiovideo',
                'participant': 'audio'
            }
        },
        'sip': {'enabled': False},
        'data': {'your_custom_key': 'any value you need'}
    }
)

# room_id is in response.json()["room"]["room_id"] — store it for later use
print(response.json())
<?php
$payload = json_encode([
    'name' => 'Weekly Team Standup',
    'owner_ref' => 'user_8821',
    'settings' => [
        'description' => 'Daily 15-minute standup for the product team',
        'mode' => 'group',
        'scheduled' => false,
        'adhoc' => false,
        'duration' => 30,
        'moderators' => '1',
        'participants' => '10',
        'quality' => 'HD',
        'auto_recording' => false,
        'screen_share' => true,
        'canvas' => false,
        'knock' => false,
        'wait_for_moderator' => false,
        'abwd' => true,
        'max_active_talkers' => 4,
        'media_zone' => 'XX',
        'single_file_recording' => false,
        'role_based_recording' => [
            'moderator' => 'audiovideo',
            'participant' => 'audio'
        ]
    ],
    'sip' => ['enabled' => false],
    'data' => ['your_custom_key' => 'any value you need']
]);

$ch = curl_init('https://api.enablex.io/video/v2/rooms');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);

$result = json_decode(curl_exec($ch), true);
curl_close($ch);

// room_id is in $result['room']['room_id'] — store it for later use
echo $result['room']['room_id'];

Request Parameters

ParameterTypeRequiredDescription
namestringYesDisplay name for the room or meeting topic.
owner_refstringYesAn identifier from your own system (e.g. user ID). Appears in post-session reports for your reference.
settings.modestringNogroup (default) or lecture. Lecture mode restricts publishing to moderators only.
settings.audio_onlybooleanNoDefault: false. Set true to restrict the room to audio-only calls.
settings.scheduledbooleanNoDefault: false. Set true for a Scheduled Room.
settings.scheduled_timestringScheduled onlyUTC scheduled start time in YYYY-MM-DD HH:MM:SS format. Tokens can be created 30 minutes before this time.
settings.adhocbooleanNoDefault: false. Set true for an Adhoc Room.
settings.durationnumberScheduled onlySession duration in minutes (min: 10). Required for Scheduled Rooms. Not applicable for Permanent or Adhoc.
settings.moderatorsnumberNoMaximum number of moderators allowed in the room.
settings.participantsnumberNoMaximum number of participants. Up to 300 for scheduled rooms; up to 1000 in lecture mode.
settings.audiencesnumberNoMaximum HLS audience viewers. Required only if HLS streaming is enabled.
settings.qualitystringNoHD (up to 1280×720), SD (up to 640×480), or LD (up to 640×360). Defaults to your subscription setting.
settings.auto_recordingbooleanNoDefault: false. Automatically starts recording when the first participant publishes a stream.
settings.screen_sharebooleanNoDefault: true. Enables screen sharing in the session.
settings.canvasbooleanNoDefault: false. Enables canvas streaming (compositing HTML5 canvas content as a stream).
settings.knockbooleanNoDefault: false. Enables moderated entry — moderator must approve each participant before they join.
settings.wait_for_moderatorbooleanNoDefault: false. Participants wait in a lobby until a moderator joins.
settings.abwdbooleanNoDefault: false. Enables Automatic Bandwidth Detection for adaptive video quality.
settings.max_active_talkersnumberNoRange: 1–16. Default: 16. Number of simultaneous video streams visible to all participants.
settings.media_zonestringNoIN (India), SG (Singapore), US (United States), XX (auto-assign). Determines which media servers handle this room.
settings.single_file_recordingbooleanNoDefault: false. For 2-user rooms: produces a single transcoded WEBM file immediately after session ends.
settings.role_based_recordingobjectNoControl which tracks are recorded per role. See sub-fields below.
settings.role_based_recording.moderatorstringNoaudiovideo (default) or audio. Use audio to exclude video from moderator recordings.
settings.role_based_recording.participantstringNoaudiovideo (default) or audio.
settings.watermarkbooleanNoDefault: false. Adds a watermark to recorded files.
settings.rtmp_streamingobjectNoConfigure RTMP live streaming. streaming: true enables live push; recording: true records the RTMP stream.
sip.enabledbooleanNoDefault: false. Enables PSTN/SIP dial-in for this room.
dataobjectNoFree-form key-value store for your application's custom metadata. Returned in all room responses.

Response

{
  "result": 0,
  "room": {
    "name": "Weekly Team Standup",
    "owner_ref": "user_8821",
    "settings": {
      "description": "Daily 15-minute standup for the product team",
      "mode": "group",
      "scheduled": false,
      "adhoc": false,
      "duration": 30,
      "moderators": "1",
      "participants": "10",
      "billing_code": "",
      "auto_recording": false,
      "quality": "HD",
      "screen_share": true,
      "canvas": false,
      "max_active_talkers": 4,
      "role_based_recording": {
        "moderator": "audiovideo",
        "participant": "audio"
      }
    },
    "sip": {
      "enabled": false
    },
    "data": {
      "your_custom_key": "any value you need"
    },
    "created": "2024-03-15T09:30:00.000Z",
    "room_id": "64f3a1b2c8e94d001f2e3a77"
  }
}
Save the room_id

The room_id returned in the response is the permanent identifier for this room. Store it in your database — you will need it to create tokens, update the room, and retrieve reports.

Try this endpoint in the Open API Tool →

List All Rooms

Returns all rooms created under your application. Use this to display a room directory, check existing configurations, or sync room data with your own database.

curl https://api.enablex.io/video/v2/rooms \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const response = await axios.get(
  'https://api.enablex.io/video/v2/rooms',
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

response = requests.get(
    'https://api.enablex.io/video/v2/rooms',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$ch = curl_init('https://api.enablex.io/video/v2/rooms');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Response

{
  "result": 0,
  "rooms": [
    {
      "name": "Weekly Team Standup",
      "owner_ref": "user_8821",
      "settings": {
        "mode": "group",
        "scheduled": false,
        "adhoc": false,
        "duration": 30,
        "moderators": "1",
        "participants": "10",
        "auto_recording": false,
        "quality": "HD",
        "screen_share": true,
        "max_active_talkers": 4
      },
      "sip": {
        "enabled": false
      },
      "data": {},
      "created": "2024-03-15T09:30:00.000Z",
      "room_id": "64f3a1b2c8e94d001f2e3a77"
    }
  ]
}

Try this endpoint in the Open API Tool →

Get Room Details

Returns the complete configuration of a single room. Use this to verify room settings before a session starts or to display room details in your application UI.

curl https://api.enablex.io/video/v2/rooms/{room_id} \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const roomId = 'YOUR_ROOM_ID';

const response = await axios.get(
  `https://api.enablex.io/video/v2/rooms/${roomId}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

room_id = 'YOUR_ROOM_ID'

response = requests.get(
    f'https://api.enablex.io/video/v2/rooms/{room_id}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$roomId = 'YOUR_ROOM_ID';

$ch = curl_init("https://api.enablex.io/video/v2/rooms/{$roomId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Path Parameters

ParameterDescription
room_idThe ID of the room returned when the room was created.

Response

Same structure as the Create Room response — a single room object with all settings.

Try this endpoint in the Open API Tool →

Update a Room

Modifies an existing room's settings. You only need to include the fields you want to change — the API performs a partial update (PATCH). Settings that are not included in the request body remain unchanged.

When Changes Take Effect
  • Changes apply to subsequent sessions only. An ongoing session is not affected.
  • Scheduled rooms can only be updated up to 30 minutes before their scheduled start time.
PATCH https://api.enablex.io/video/v2/rooms/{room_id}
Authorization: Basic <base64(APP_ID:APP_KEY)>
Content-Type: application/json

Request Body (partial update)

curl -X PATCH https://api.enablex.io/video/v2/rooms/{room_id} \
  -u YOUR_APP_ID:YOUR_APP_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekly Team Standup — Revised",
    "settings": {
      "participants": "15",
      "auto_recording": true
    }
  }'  
const axios = require('axios');

const roomId = 'YOUR_ROOM_ID';

const response = await axios.patch(
  `https://api.enablex.io/video/v2/rooms/${roomId}`,
  {
    name: 'Weekly Team Standup — Revised',
    settings: {
      participants: '15',
      auto_recording: true
    }
  },
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

room_id = 'YOUR_ROOM_ID'

response = requests.patch(
    f'https://api.enablex.io/video/v2/rooms/{room_id}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY'),
    json={
        'name': 'Weekly Team Standup — Revised',
        'settings': {
            'participants': '15',
            'auto_recording': True
        }
    }
)

print(response.json())
<?php
$roomId = 'YOUR_ROOM_ID';

$payload = json_encode([
    'name' => 'Weekly Team Standup — Revised',
    'settings' => [
        'participants' => '15',
        'auto_recording' => true
    ]
]);

$ch = curl_init("https://api.enablex.io/video/v2/rooms/{$roomId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Response

{
  "result": 0
}

Try this endpoint in the Open API Tool →

Delete a Room

Permanently removes a room and all its configuration from the EnableX platform. This operation cannot be undone. A room can only be deleted when no active session is running inside it.

Cannot Delete an Active Room

If a session is currently in progress, the API returns an error. End the session first, then delete the room. Post-session data (CDR, archives) is still accessible after deletion.

curl -X DELETE https://api.enablex.io/video/v2/rooms/{room_id} \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const roomId = 'YOUR_ROOM_ID';

const response = await axios.delete(
  `https://api.enablex.io/video/v2/rooms/${roomId}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data); // { result: 0 }
import requests
from requests.auth import HTTPBasicAuth

room_id = 'YOUR_ROOM_ID'

response = requests.delete(
    f'https://api.enablex.io/video/v2/rooms/{room_id}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json()) # { "result": 0 }
<?php
$roomId = 'YOUR_ROOM_ID';

$ch = curl_init("https://api.enablex.io/video/v2/rooms/{$roomId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Response

{
  "result": 0
}

Try this endpoint in the Open API Tool →

Session Access

Create a Token

A token is a short-lived credential that authorises a specific user to join a specific room. Your application server creates a token for each user whenever they want to join a session. The token is then passed to the client-side SDK, which uses it to connect to the EnableX media infrastructure.

Token Rules

  • Tokens are single-use. Once used to join a session, they cannot be reused.
  • Tokens expire 15 minutes after creation. They must be used within this window.
  • Each token is tied to a specific room_id. It cannot be used to join a different room.
  • The user's role (moderator, participant, viewer, audience) is embedded in the token at creation time and cannot be changed afterwards.
  • Tokens for Permanent rooms can be created at any time.
  • Tokens for Scheduled rooms can only be created from 30 minutes before the scheduled start time.

User Roles

RoleCapabilities
moderatorFull session control: can start/stop recording, mute/unmute participants, eject users, and end the session for everyone.
participantCan publish and subscribe to all media streams. Standard attendee role.
viewerCan subscribe to all media streams and use chat, but cannot publish audio or video.
audienceReceives only the HLS broadcast stream. Suitable for large audiences watching a live stream.
POST https://api.enablex.io/video/v2/rooms/{room_id}/tokens
Authorization: Basic <base64(APP_ID:APP_KEY)>
Content-Type: application/json

Request Body

curl -X POST https://api.enablex.io/video/v2/rooms/{room_id}/tokens \
  -u YOUR_APP_ID:YOUR_APP_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sarah Johnson",
    "role": "participant",
    "user_ref": "usr_4921",
    "data": {
      "department": "engineering",
      "avatar_url": "https://example.com/avatars/sarah.jpg"
    }
  }'  
const axios = require('axios');

const roomId = 'YOUR_ROOM_ID';

const response = await axios.post(
  `https://api.enablex.io/video/v2/rooms/${roomId}/tokens`,
  {
    name: 'Sarah Johnson',
    role: 'participant',
    user_ref: 'usr_4921',
    data: {
      department: 'engineering',
      avatar_url: 'https://example.com/avatars/sarah.jpg'
    }
  },
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

// Pass response.data.token to the Video SDK on the client side
console.log(response.data.token);
import requests
from requests.auth import HTTPBasicAuth

room_id = 'YOUR_ROOM_ID'

response = requests.post(
    f'https://api.enablex.io/video/v2/rooms/{room_id}/tokens',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY'),
    json={
        'name': 'Sarah Johnson',
        'role': 'participant',
        'user_ref': 'usr_4921',
        'data': {
            'department': 'engineering',
            'avatar_url': 'https://example.com/avatars/sarah.jpg'
        }
    }
)

# Pass the token to the Video SDK on the client side
print(response.json()['token'])
<?php
$roomId = 'YOUR_ROOM_ID';

$payload = json_encode([
    'name' => 'Sarah Johnson',
    'role' => 'participant',
    'user_ref' => 'usr_4921',
    'data' => [
        'department' => 'engineering',
        'avatar_url' => 'https://example.com/avatars/sarah.jpg'
    ]
]);

$ch = curl_init("https://api.enablex.io/video/v2/rooms/{$roomId}/tokens");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);

$result = json_decode(curl_exec($ch), true);
curl_close($ch);

// Pass $result['token'] to the Video SDK on the client side
echo $result['token'];

Request Parameters

ParameterTypeRequiredDescription
namestringYesDisplay name shown to other participants in the session.
rolestringYesmoderator, participant, viewer, or audience.
user_refstringYesYour application's user identifier. Included in CDR reports for post-session analysis.
dataobjectNoCustom key-value pairs associated with this user. Delivered to other participants via SDK events.

Response

{
  "result": 0,
  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}

The token is a signed JWT. Pass it to the Video SDK's join method on the client side. It encodes the room, user identity, role, and expiry — you do not need to decode it.

Request Tokens Just-in-Time

Create tokens immediately before a user joins — not hours in advance. Since tokens expire in 15 minutes, generating them too early wastes the window and forces you to create another one anyway.

Try this endpoint in the Open API Tool →

Get Active Users in a Session

Returns a list of all users currently connected to a room during an active session. If the room has no ongoing session, the response returns an empty list. Use this to display a live participant roster, check whether a moderator is present, or audit who is in a session.

curl https://api.enablex.io/video/v2/rooms/{room_id}/users \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const roomId = 'YOUR_ROOM_ID';

const response = await axios.get(
  `https://api.enablex.io/video/v2/rooms/${roomId}/users`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

room_id = 'YOUR_ROOM_ID'

response = requests.get(
    f'https://api.enablex.io/video/v2/rooms/{room_id}/users',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$roomId = 'YOUR_ROOM_ID';

$ch = curl_init("https://api.enablex.io/video/v2/rooms/{$roomId}/users");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Response

{
  "result": 0,
  "total": 2,
  "users": [
    {
      "name": "Sarah Johnson",
      "user_ref": "usr_4921",
      "role": "moderator",
      "permissions": {
        "publish": true,
        "subscribe": true,
        "record": true,
        "stats": true,
        "controlhandlers": true
      }
    },
    {
      "name": "Tom Lee",
      "user_ref": "usr_7734",
      "role": "participant",
      "permissions": {
        "publish": true,
        "subscribe": true,
        "record": false,
        "stats": true,
        "controlhandlers": true
      }
    }
  ]
}

Try this endpoint in the Open API Tool →

Post-Session Data

Session Archives

After a session ends, EnableX processes and stores session artifacts as an archive. Each archive record contains download URLs for the files produced during the session:

  • Recording files — Individual raw audio/video stream files (.mkv).
  • Transcoded file — A single composited, playable video (.mov) where all streams are merged into one layout.
  • Chat data — A JSON file containing all chat messages exchanged during the session.
  • Session metadata — A JSON file with session-level event data (joins, leaves, mutes, etc.).
Archive Files Require Authentication to Download

The download URLs in the archive response are not publicly accessible. To download any file, issue an HTTP GET to the URL with the same Authorization: Basic header used for all API calls. Unauthenticated requests will receive a 401 error.

You can query archives using four different filters:

By Conference Number

Each session in a room is assigned a unique conf_num (Conference Number) by the EnableX platform. Use this to retrieve the archive for one specific session.

curl https://api.enablex.io/video/v2/archive/conf/{conf_num} \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const confNum = 'CONF-882210';

const response = await axios.get(
  `https://api.enablex.io/video/v2/archive/conf/${confNum}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

conf_num = 'CONF-882210'

response = requests.get(
    f'https://api.enablex.io/video/v2/archive/conf/{conf_num}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$confNum = 'CONF-882210';

$ch = curl_init("https://api.enablex.io/video/v2/archive/conf/{$confNum}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Try in Open API Tool →

By Room

Returns all archive records ever produced in a specific room, across all sessions.

curl https://api.enablex.io/video/v2/archive/room/{room_id} \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const roomId = 'YOUR_ROOM_ID';

const response = await axios.get(
  `https://api.enablex.io/video/v2/archive/room/${roomId}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

room_id = 'YOUR_ROOM_ID'

response = requests.get(
    f'https://api.enablex.io/video/v2/archive/room/{room_id}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$roomId = 'YOUR_ROOM_ID';

$ch = curl_init("https://api.enablex.io/video/v2/archive/room/{$roomId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Try in Open API Tool →

By Room and Date Range

Filters archives for a specific room between a start and end date. Dates must be in UTC.

curl https://api.enablex.io/video/v2/archive/room-period/{room_id}/2024-03-01/2024-03-31 \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const roomId   = 'YOUR_ROOM_ID';
const fromDate = '2024-03-01';
const toDate   = '2024-03-31';

const response = await axios.get(
  `https://api.enablex.io/video/v2/archive/room-period/${roomId}/${fromDate}/${toDate}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

room_id   = 'YOUR_ROOM_ID'
from_date = '2024-03-01'
to_date   = '2024-03-31'

response = requests.get(
    f'https://api.enablex.io/video/v2/archive/room-period/{room_id}/{from_date}/{to_date}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$roomId   = 'YOUR_ROOM_ID';
$fromDate = '2024-03-01';
$toDate   = '2024-03-31';

$ch = curl_init("https://api.enablex.io/video/v2/archive/room-period/{$roomId}/{$fromDate}/{$toDate}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Date format: YYYY-MM-DD. Example: /archive/room-period/64f3a1b2.../2024-03-01/2024-03-31

Try in Open API Tool →

By Date Range (All Rooms)

Returns all archives across all rooms within the specified date range. Useful for bulk reporting.

curl https://api.enablex.io/video/v2/archive/period/2024-03-01/2024-03-31 \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const fromDate = '2024-03-01';
const toDate   = '2024-03-31';

const response = await axios.get(
  `https://api.enablex.io/video/v2/archive/period/${fromDate}/${toDate}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

from_date = '2024-03-01'
to_date   = '2024-03-31'

response = requests.get(
    f'https://api.enablex.io/video/v2/archive/period/{from_date}/{to_date}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$fromDate = '2024-03-01';
$toDate   = '2024-03-31';

$ch = curl_init("https://api.enablex.io/video/v2/archive/period/{$fromDate}/{$toDate}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Try in Open API Tool →

Archive Response Structure

{
  "result": "0",
  "archive": [
    {
      "_id": "archive_record_id",
      "trans_date": "2024-03-15T10:45:00.000Z",
      "conf_num": "CONF-882210",
      "app_id": "your_app_id",
      "room_id": "64f3a1b2c8e94d001f2e3a77",
      "recording": [
        { "url": "https://storage.enablex.io/path/stream-participant1.mkv" },
        { "url": "https://storage.enablex.io/path/stream-participant2.mkv" }
      ],
      "transcoded": [
        { "url": "https://storage.enablex.io/path/session-composited.mov" }
      ],
      "chatdata": "https://storage.enablex.io/path/chat.json",
      "metadata": "https://storage.enablex.io/path/session-meta.json"
    }
  ]
}

Call Detail Reports (CDR)

A Call Detail Report (CDR) captures per-user connection data for every participant in a session. While archives give you the recorded content, CDRs give you the usage and quality analytics. Each CDR entry represents one user's connection within one session.

CDRs are useful for:

  • Usage-based billing — calculating minutes consumed per user or room.
  • Compliance and audit — knowing who joined, from where, and for how long.
  • Quality diagnostics — reviewing bitrate stats to diagnose call quality issues post-session.
  • Operational reporting — feeding session data into your analytics dashboards.

The same four filter patterns as archives are available:

By Conference Number

curl https://api.enablex.io/video/v2/cdr/conf/{conf_num} \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const confNum = 'CONF-882210';

const response = await axios.get(
  `https://api.enablex.io/video/v2/cdr/conf/${confNum}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

conf_num = 'CONF-882210'

response = requests.get(
    f'https://api.enablex.io/video/v2/cdr/conf/{conf_num}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$confNum = 'CONF-882210';

$ch = curl_init("https://api.enablex.io/video/v2/cdr/conf/{$confNum}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

By Room

curl https://api.enablex.io/video/v2/cdr/room/{room_id} \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const roomId = 'YOUR_ROOM_ID';

const response = await axios.get(
  `https://api.enablex.io/video/v2/cdr/room/${roomId}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

room_id = 'YOUR_ROOM_ID'

response = requests.get(
    f'https://api.enablex.io/video/v2/cdr/room/{room_id}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$roomId = 'YOUR_ROOM_ID';

$ch = curl_init("https://api.enablex.io/video/v2/cdr/room/{$roomId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Try in Open API Tool →

By Room and Date Range

curl https://api.enablex.io/video/v2/cdr/room-period/{room_id}/2024-03-01/2024-03-31 \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const roomId   = 'YOUR_ROOM_ID';
const fromDate = '2024-03-01';
const toDate   = '2024-03-31';

const response = await axios.get(
  `https://api.enablex.io/video/v2/cdr/room-period/${roomId}/${fromDate}/${toDate}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

room_id   = 'YOUR_ROOM_ID'
from_date = '2024-03-01'
to_date   = '2024-03-31'

response = requests.get(
    f'https://api.enablex.io/video/v2/cdr/room-period/{room_id}/{from_date}/{to_date}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$roomId   = 'YOUR_ROOM_ID';
$fromDate = '2024-03-01';
$toDate   = '2024-03-31';

$ch = curl_init("https://api.enablex.io/video/v2/cdr/room-period/{$roomId}/{$fromDate}/{$toDate}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Try in Open API Tool →

By Date Range (All Rooms)

curl https://api.enablex.io/video/v2/cdr/period/2024-03-01/2024-03-31 \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const fromDate = '2024-03-01';
const toDate   = '2024-03-31';

const response = await axios.get(
  `https://api.enablex.io/video/v2/cdr/period/${fromDate}/${toDate}`,
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

from_date = '2024-03-01'
to_date   = '2024-03-31'

response = requests.get(
    f'https://api.enablex.io/video/v2/cdr/period/{from_date}/{to_date}',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$fromDate = '2024-03-01';
$toDate   = '2024-03-31';

$ch = curl_init("https://api.enablex.io/video/v2/cdr/period/{$fromDate}/{$toDate}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Try in Open API Tool →

CDR Response Structure

{
  "result": "0",
  "cdr": [
    {
      "conf_num": "CONF-882210",
      "call_num": "CALL-441",
      "call_log_id": "LOG-99182",
      "trans_date": "2024-03-15T10:45:00.000Z",
      "app_id": "your_app_id",
      "cdr_id": "cdr_001122",
      "sip": false,
      "lowcode": false,
      "room": {
        "room_id": "64f3a1b2c8e94d001f2e3a77",
        "connect_dt": "2024-03-15T10:00:00.000Z",
        "disconnect_dt": "2024-03-15T10:45:00.000Z",
        "duration": 2700,
        "room_details": {}
      },
      "user": {
        "role": "participant",
        "name": "Sarah Johnson",
        "ref": "usr_4921",
        "ip": "203.0.113.42",
        "agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)..."
      },
      "published_track": {
        "audio": true,
        "video": true,
        "screen": false,
        "data": false,
        "url": false
      },
      "usage": {
        "published_minutes": 44,
        "screen_minutes": 0,
        "connect_minutes": 45,
        "connect_minutes_cal": 45,
        "room_connect_minutes": 45
      },
      "stats_quality": {
        "send": {
          "audio": {
            "avg_bitrate": 40960,
            "avg_bitrate_quality": "Good",
            "max_bitrate": 48000,
            "min_bitrate": 38000
          },
          "video": {
            "avg_bitrate": 512000,
            "avg_bitrate_quality": "Good",
            "max_bitrate": 720000,
            "min_bitrate": 256000
          }
        },
        "receive": {
          "audio": {
            "avg_bitrate": 41020,
            "avg_bitrate_quality": "Good",
            "max_bitrate": 42752,
            "min_bitrate": 38231,
            "bitrate_good_percent": 100,
            "bitrate_moderate_percent": 0,
            "bitrate_bad_percent": 0
          },
          "video": {
            "avg_bitrate": 480000,
            "avg_bitrate_quality": "Good",
            "max_bitrate": 680000,
            "min_bitrate": 200000,
            "bitrate_good_percent": 95,
            "bitrate_moderate_percent": 4,
            "bitrate_bad_percent": 1
          }
        },
        "call_quality": "Good"
      }
    }
  ]
}

Key CDR Fields Explained

FieldMeaning
conf_numSession identifier assigned by EnableX. One session = one conf_num; one room may have many sessions over its lifetime.
call_numPer-user connection identifier within a session. Unique to each participant per session.
call_log_idEnableX internal log ID. Share this with EnableX support when reporting a session quality issue.
room.durationTotal seconds the user was connected to the room.
usage.connect_minutes_calBillable minutes — rounded up to the next minute from raw connection time.
usage.published_minutesSeconds during which the user was actively publishing their own audio/video stream.
published_trackWhich media types the user published: audio, video, screen share, data channel, or URL.
stats_quality.call_qualityOverall call quality assessment: Good or Bad.
stats_quality.send / receivePer-stream bitrate stats for audio, video, and screen share in both directions.
Dial-In

Dial-In Phone Numbers

If your EnableX subscription includes PSTN/SIP dial-in, participants can join a video session by calling a phone number rather than connecting through the browser or app. This is useful for participants who are in a low-bandwidth environment or prefer a voice-only experience.

This endpoint returns the dial-in phone numbers configured for your account along with the SIP server details used when integrating at the infrastructure level.

Subscription Required

PSTN dial-in is a subscription-controlled feature. The response will be empty or return an error if your account does not have this capability enabled. Contact EnableX support to activate it.

curl https://api.enablex.io/video/v2/dialin/ \
  -u YOUR_APP_ID:YOUR_APP_KEY
const axios = require('axios');

const response = await axios.get(
  'https://api.enablex.io/video/v2/dialin/',
  {
    auth: {
      username: 'YOUR_APP_ID',
      password: 'YOUR_APP_KEY'
    }
  }
);

console.log(response.data);
import requests
from requests.auth import HTTPBasicAuth

response = requests.get(
    'https://api.enablex.io/video/v2/dialin/',
    auth=HTTPBasicAuth('YOUR_APP_ID', 'YOUR_APP_KEY')
)

print(response.json())
<?php
$ch = curl_init('https://api.enablex.io/video/v2/dialin/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, 'YOUR_APP_ID:YOUR_APP_KEY');

$response = curl_exec($ch);
curl_close($ch);
echo $response;

Response

{
  "_id": "account_object_id",
  "app_key": "your_app_id",
  "settings": {
    "sip": true
  },
  "sip": {
    "server_url": "sip://sip.enablex.io:5060",
    "username": "sip_username",
    "password": "sip_password",
    "sig_servers": [
      "203.0.113.10",
      "203.0.113.11"
    ],
    "media_servers": [
      "203.0.113.20",
      "203.0.113.21"
    ]
  },
  "dialin": [
    {
      "country": "United States",
      "country_code": "+1",
      "phone": "+18005551234",
      "toll": false
    },
    {
      "country": "India",
      "country_code": "+91",
      "phone": "+918001234567",
      "toll": false
    }
  ]
}

Response Fields

FieldDescription
sip.server_urlSIP server endpoint for infrastructure-level integration.
sip.sig_serversSignalling server IPs. Used for SIP trunk configuration.
sip.media_serversMedia server IPs. Whitelist these in your firewall if needed.
dialin[].phoneThe phone number participants call to join a session.
dialin[].tollfalse indicates a toll-free number.