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()
  1. Configure the streaming profile as described in Getting Started.
  2. Obtain the dialogId and, if needed, the segmentId for the interaction.
  3. Generate a deterministic streamId in your system.
  4. Start a dialog-level or segment-level stream with your receiver URL.
  5. Stop the stream with the matching streamId when media capture is no longer needed.

Warning

Media control changes affect live audio handling. Confirm consent, retention, and compliance requirements before starting streams automatically.