Media Control APIs
The Media Control APIs let you start and stop audio streams for a dialog or a specific segment. Use them with call streaming integrations when media should be captured selectively instead of streamed for every eligible interaction.
Strategic Overview
Call streaming profiles define where audio can be streamed. Media control endpoints let an integration decide when to start or stop streaming for a specific interaction after it has identified the dialog or segment that should be processed.
Key Use Cases
- Selective Live Analytics: Start a stream only when a workflow determines that live analysis is needed.
- Compliance Control: Stop streaming before sensitive information is discussed.
- Targeted Recording Pipelines: Stream only selected segments to external storage or AI services.
- Transfer-Aware Processing: Stream only the dialog or agent segment that needs downstream analysis, storage, or compliance handling.
Real-Time vs. Configuration APIs
Media control acts on live media routing. It does not create the streaming profile or historical recording after the fact. Configure call streaming first, then use these endpoints while the dialog or segment is still eligible for live streaming.
Required Permissions & Scopes
1. Configure OAuth Scopes
To authenticate, your application must be configured with the following permission in the Developer Portal:
ReadAccounts: Required to validate account context and access RingCX integration APIs.
2. Enable RingCX Admin Access
The account must be configured for call streaming before media-control requests can be honored. See Call Streaming Getting Started for streaming profile setup.
The user authenticating the app must also have access to the RingCX sub-account that owns the dialog.
Common Authorization Errors
If the application has the correct OAuth scope but the user or account is not authorized for the requested media action, the API returns an error similar to:
{
"errorCode": "access.denied.exception",
"generalMessage": "You do not have permission to access this resource",
"timestamp": 1611847650696
}
Rate Limiting & Stability
Media control requests publish start/stop events to the media-control service. Do not retry blindly after network timeouts because duplicate start events with the same streamId can create ambiguous state. Use a deterministic streamId, check your receiver logs, and retry with exponential backoff only when you know the previous request did not reach the platform.
Identifiers
Media control requires interaction identifiers from another workflow.
Dialog vs. Segment
A dialog represents the overall interaction. A segment represents one participant leg or portion of that interaction. For example, if a customer speaks with Agent 1 and is then transferred to Agent 2, both agent conversations belong to the same dialog, but each agent leg has its own segment.
Use dialog-level streaming when the receiver needs media for the full interaction. Use segment-level streaming when the receiver only needs one specific leg, such as a single agent's portion of a transferred call.
| Identifier | Type | Requirement | Description |
|---|---|---|---|
rcAccountId |
String | Required | RingCentral account ID. |
subAccountId |
String | Required | RingCX sub-account ID that owns the dialog. |
dialogId |
String | Required | Identifier for the overall interaction. Capture it from the live interaction workflow that decides to start streaming, or from interaction metadata once the interaction is available to your integration. |
segmentId |
String | Optional | Identifier for one participant leg or portion of the dialog. Capture it from the same interaction metadata source as the dialog when segment-level routing is required. |
streamId |
String | Required | Caller-provided stream identifier. You choose this value when starting the stream and reuse it to stop the same stream. |
Info
The start endpoints return 200 OK with no response body. The streamId is not generated by the API; it is supplied in the start-stream request body.
Start a Dialog-Level Stream
Starts a stream for the full dialog.
POST https://ringcx.ringcentral.com/voice/api/cx/integration/v1/accounts/{rcAccountId}/sub-accounts/{subAccountId}/dialogs/{dialogId}/streams
API Reference: Start dialog stream
Request Body
The request body matches the StartStreamRequestDTO schema (with a nested AudioStreamProperties object).
| Parameter | Type | Requirement | Description |
|---|---|---|---|
url |
String | Required | Destination URL that will receive the audio stream. |
streamId |
String | Required | Unique identifier you assign to this stream. Use the same value when stopping the stream. |
token |
String | Optional | Opaque token passed through to the media-control layer for the stream receiver. |
properties.encoding |
String | Optional | Requested audio encoding. The API surface treats this as free-form; use values supported by the configured streaming profile. |
properties.rate |
Integer (int32) |
Optional | Requested sample rate in Hz. The API surface does not publish an enum; align it with the configured streaming profile. |
properties.ptime |
Integer (int32) |
Optional | Requested packetization time in milliseconds. The API surface does not publish an enum; align it with the configured streaming profile. |
Example Request:
{
"url": "wss://media.example.com/ringcx/audio",
"streamId": "crm-case-4472-dialog",
"token": "receiver-auth-token",
"properties": {
"encoding": "PCMU",
"rate": 8000,
"ptime": 20
}
}
Response
The API returns 200 OK with an empty body after the start event is accepted for publishing.
Start a Segment-Level Stream
Starts a stream for one segment within a dialog.
POST https://ringcx.ringcentral.com/voice/api/cx/integration/v1/accounts/{rcAccountId}/sub-accounts/{subAccountId}/dialogs/{dialogId}/segments/{segmentId}/streams
API Reference: Start segment stream
Use segment-level streaming when only one agent leg or participant segment should be sent to the receiver.
Example Request:
{
"url": "wss://media.example.com/ringcx/audio",
"streamId": "qa-review-4472-agent-segment",
"properties": {
"encoding": "PCMU",
"rate": 8000,
"ptime": 20
}
}
Stop a Stream
Stop requests use the same streamId you supplied when starting the stream.
| Scope | Endpoint | API Reference |
|---|---|---|
| Dialog | DELETE https://ringcx.ringcentral.com/voice/api/cx/integration/v1/accounts/{rcAccountId}/sub-accounts/{subAccountId}/dialogs/{dialogId}/streams/{streamId} |
Stop dialog stream |
| Segment | DELETE https://ringcx.ringcentral.com/voice/api/cx/integration/v1/accounts/{rcAccountId}/sub-accounts/{subAccountId}/dialogs/{dialogId}/segments/{segmentId}/streams/{streamId} |
Stop segment stream |
Stop Parameters
| Parameter | Type | Requirement | Description |
|---|---|---|---|
rcAccountId |
String | Required | RingCentral account ID. |
subAccountId |
String | Required | RingCX sub-account ID. |
dialogId |
String | Required | Dialog that owns the stream. |
segmentId |
String | Required for segment stop | Segment that owns the stream. |
streamId |
String | Required | Stream identifier supplied when the stream was started. |
The API returns 200 OK with an empty body after the stop event is accepted for publishing.
Common Errors
| Status | Cause | Resolution |
|---|---|---|
400 Bad Request |
Missing url or streamId, or malformed request body. |
Send both required fields and validate the JSON body. |
403 Forbidden |
Account/user is not authorized for media control or the sub-account mapping is invalid. | Confirm account mapping, OAuth scope, and streaming access. |
404 Not Found |
Dialog or segment is no longer addressable. | Start streams while the interaction is active or still eligible for media control. |
409 Conflict |
Duplicate or conflicting stream state. | Use deterministic streamId values and avoid parallel start/stop calls for the same stream. |
Sample Implementation (Python)
import requests
BASE_URL = "https://ringcx.ringcentral.com/voice/api"
def start_segment_stream(token, rc_account_id, sub_account_id, dialog_id, segment_id, stream_id):
url = (
f"{BASE_URL}/cx/integration/v1/accounts/{rc_account_id}"
f"/sub-accounts/{sub_account_id}/dialogs/{dialog_id}"
f"/segments/{segment_id}/streams"
)
body = {
"url": "wss://media.example.com/ringcx/audio",
"streamId": stream_id,
"properties": {
"encoding": "PCMU",
"rate": 8000,
"ptime": 20,
},
}
response = requests.post(url, headers={"Authorization": f"Bearer {token}"}, json=body)
response.raise_for_status()
def stop_segment_stream(token, rc_account_id, sub_account_id, dialog_id, segment_id, stream_id):
url = (
f"{BASE_URL}/cx/integration/v1/accounts/{rc_account_id}"
f"/sub-accounts/{sub_account_id}/dialogs/{dialog_id}"
f"/segments/{segment_id}/streams/{stream_id}"
)
response = requests.delete(url, headers={"Authorization": f"Bearer {token}"})
response.raise_for_status()
Recommended Workflow
- Configure the streaming profile as described in Getting Started.
- Obtain the
dialogIdand, if needed, thesegmentIdfor the interaction. - Generate a deterministic
streamIdin your system. - Start a dialog-level or segment-level stream with your receiver URL.
- Stop the stream with the matching
streamIdwhen media capture is no longer needed.
Warning
Media control changes affect live audio handling. Confirm consent, retention, and compliance requirements before starting streams automatically.