Skip to content

Connect a Coze Agent through TiRTC

This guide walks through the complete working path: a device sends microphone audio to Tange through TiRTC, Tange connects to your Coze agent, and the agent's voice response returns to the device over the same TiRTC connection.

Follow the steps in order for your first integration.

Architecture

TiRTC and Coze agent integration flow

There are four responsibilities:

ComponentResponsibility
Coze consoleCreate the agent and an API Key.
Tange role configurationStore the Coze credential and bot_id, then provide a role_id.
Application serverRequest a short-lived peer_id and token for device_id + role_id, then deliver them to the device.
DeviceConnect with TiRTC, send start_session, upload microphone audio, and play response audio.

Do not confuse these IDs:

  • bot_id is the Coze agent ID and is used only in the Tange role configuration.
  • role_id is the Tange role ID and is used to request credentials and start a session.
  • device_id identifies the registered Tange device.

Prerequisites

  • You can sign in to the Coze console.
  • You have a Coze agent that can answer correctly and you have recorded its bot_id.
  • You have created a Tange application and device and have the Tange AppId.
  • Your application server can call Tange server APIs.
  • The device has integrated the TiRTC SDK and can connect, exchange audio, and exchange commands.

If TiRTC is not working yet, finish Device Integration first.

Step 1: Create a Coze agent and API Key

Create and test the agent

If you have not created a Coze agent before, start with the Coze Agent Quick Start.

  1. Create the agent in Coze.
  2. Verify the conversation in the Coze debugging page.
  3. Make sure the agent is available to API calls. Publish it first if required by the console.
  4. Record its bot_id; the agent name is not the bot_id.

Create the credential

Open the Coze Playground authorization page, then open API & SDK → Authorization → Service identities and credentials to create an API Key. Grant only the permissions needed to call the target agent and real-time voice APIs. Copy the API Key immediately and keep it only on the server.

Open Authorization and Service identities and credentials in Coze Playground

The red boxes mark Authorization and Service identities and credentials. On this page, click Add in the upper-right corner.

Save this value immediately:

Coze credential valueTange role field
API Keyservice_config.config.api_key

Step 2: Create a Coze role in Tange

Follow the Create Role API documentation. Set the role type to coze, provide the Coze api_key and bot_id, then create the role.

Store the returned role_id; it is required when requesting connection credentials and sending start_session.

Step 3: Request TiRTC connection credentials

The application server uses the same device_id and role_id to request peer_id + token. See Server Integration for the endpoint, signing method, request fields, and error handling.

Deliver only device_id, role_id, peer_id, and token to the device. The device must not construct peer_id or store the Tange AK/SK.

Step 4: Connect and start the session

The device must perform these operations in order:

  1. Initialize and start the TiRTC SDK.
  2. Register the audio callback and on_command callback.
  3. Call TiRtcWhipConnect(peer_id, token, ...).
  4. Wait for the connection callback with err == 0.
  5. Send start_session on command 0x2100.
  6. Wait for the matching successful JSON-RPC response.
  7. Start sending microphone audio and playing downlink audio according to the formats in the response.
json
{
  "jsonrpc": "2.0",
  "id": "start-session-001",
  "method": "start_session",
  "params": {
    "device_id": "DEMO_DEVICE_01",
    "role_id": "role_xxx",
    "input_audio": {
      "codec": "opus",
      "sample_rate": 16000,
      "channels": 1
    },
    "output_audio": {
      "codec": "opus",
      "sample_rate": 16000,
      "channels": 1
    }
  }
}

device_id and role_id must exactly match the values used to request peer_id + token. Otherwise the platform returns:

json
{
  "jsonrpc": "2.0",
  "id": "start-session-001",
  "error": {
    "code": -32602,
    "message": "start_session params do not match WHIP token"
  }
}

Use the audio formats in the successful response as the authoritative session formats.

Step 5: Send and receive audio

The uplink frame format must match start_session.result.input_audio. Decode downlink frames according to start_session.result.output_audio and play them continuously; do not wait for the whole sentence.

Coze event protocol

Audio and control data use separate channels:

ChannelContent
TiRTC audio channelActual Coze response audio.
TiRTC command 0x2100start_session responses, forwarded Coze state events, and session termination.

Forwarded Coze events

The original Coze event is wrapped in method=forward:

json
{
  "jsonrpc": "2.0",
  "id": "<coze_event_id>",
  "method": "forward",
  "params": {
    "id": "<coze_event_id>",
    "event_type": "conversation.audio.sentence_start",
    "data": {},
    "detail": {
      "logid": "<coze_log_id>"
    }
  }
}

Handle these three event types:

params.event_typeMeaningRecommended action
conversation.audio.sentence_startCoze starts generating response audio.Enter the speaking UI state and prepare the playback buffer.
conversation.audio.completedCoze has completed response-audio generation.Return to listening after the local playback buffer is empty.
conversation.chat.canceledThe current Coze chat was canceled.Stop and clear buffered response audio immediately.

The top-level id correlates the Coze event. The device does not need to send a JSON-RPC response for these downlink forward events.

The following events are currently internal or log-only and are not forwarded unchanged: chat.created, conversation.chat.created, conversation.message.completed, conversation.chat.completed, conversation.chat.failed, conversation.audio_transcript.completed, input_audio_buffer.speech_started, and input_audio_buffer.speech_stopped.

Current adapter limitations

The Coze adapter is not the generic AI Chat pipeline. Do not assume it emits generic caption, round_start, round_end, or device_action events.

Device methodCurrent Coze behavior
start_sessionSupported and required.
end_sessionSupported; closes the current Tange and Coze session.
forwardSupported; forwards params as a native Coze client event. This is an advanced feature.
interrupt / interuptNot translated into a Coze cancel event by the current adapter.
submit_speechNot forwarded; the default path relies on Coze server VAD.
update_configNot forwarded and does not dynamically change the Coze chat.update configuration.

If native Coze control is required, send a forward message whose params exactly matches the Coze real-time protocol version in use:

json
{
  "jsonrpc": "2.0",
  "method": "forward",
  "params": {
    "id": "coze-client-event-001",
    "event_type": "<native Coze client event type>",
    "data": {}
  }
}

See Event Protocol for the common JSON-RPC format and other AI Chat service types.

Minimum acceptance test

  1. Verify the agent directly in the Coze debugger.
  2. Create the Coze API Key and verify that api_key and bot_id are present.
  3. Create the Tange coze role and store its role_id.
  4. Request peer_id + token with device_id + role_id.
  5. Confirm that the TiRTC connection callback reports err == 0.
  6. Send start_session and receive a successful response with the same id.
  7. Send clear 16 kHz mono speech continuously.
  8. Confirm that downlink audio is received and played continuously, and log forward events for diagnosis.

Once step 8 succeeds, the minimum path is complete. Validate captions, interruption, dynamic configuration, and device plugins separately only if your product requires them.

Troubleshooting

start_session params do not match WHIP token

The device_id or role_id in start_session differs from the value used to request peer_id + token. Do not reuse credentials from another device, role, or old session.

Connected, but no response

Check the following in order:

  1. start_session succeeded.
  2. The uplink codec, sample rate, channels, and TiRTC frame flags agree.
  3. The Coze bot_id is correct and the agent is available through APIs.
  4. The Coze API Key has the required target-agent and real-time voice permissions.
  5. Platform logs do not contain Coze authentication or WebSocket errors.

Events arrive, but there is no sound

Receive sound from the TiRTC audio callback, not from forward. Decode it with start_session.result.output_audio.codec and play it continuously.

Audio works, but caption does not arrive

This is a current Coze adapter difference. Coze transcript events are not mapped to the generic caption event, so caption must not be used as the success condition for Coze audio.

Coze continues after interrupt

The current adapter does not translate the generic interrupt method into a native Coze cancel event. The device may stop local playback immediately, but server-side cancellation requires a supported native Coze event through forward or a future formal mapping.

Production checklist

  • [ ] The Coze agent is tested and available through APIs.
  • [ ] The Coze API Key follows least privilege and is stored only on the server.
  • [ ] The Tange role type is coze, and the correct role_id is stored.
  • [ ] The application server requests peer_id + token; the device never constructs them.
  • [ ] start_session.device_id + role_id exactly match the credential request.
  • [ ] The device sends and receives audio according to negotiated formats.
  • [ ] The device handles the three currently forwarded Coze events.
  • [ ] The product does not depend on generic events that the current Coze adapter does not emit.
  • [ ] Network loss, failures, cancellation, and normal exit all use idempotent cleanup.

AI Chat