Skip to content

Event Protocol

AI Chat control events are sent through the TiRTC command channel. All payloads are UTF-8 JSON-RPC 2.0 messages, and the AI Chat command word is:

c
#define TIRTC_AI_SIGNALING 0x2100

Note

This command word 0x2100 belongs to the developer application reserved range (0x2000 ~ 0xffff) and is not an internal SDK reserved command. You may change this value according to your project needs, as long as the device and application server agree on it and it does not conflict with TiRTC internal commands (which are under 0x2000).

Message Types

TypeSignalDescription
RequestHas an id fieldThe sender expects a success or error response, such as start_session.
NotificationHas no id fieldOne-way event, such as caption or interrupt.

Use a string value for id. JSON-RPC responses from the platform do not include method; match them with the original request by id.

Common request:

json
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "method": "start_session",
  "params": {}
}

Common success response:

json
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "result": {}
}

Common error response:

json
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "error": {
    "code": -32602,
    "message": "Invalid params"
  }
}

Event Summary

methodDirectionTypeDescription
start_sessionDevice -> PlatformRequestStarts an AI Chat session after TiRTC is connected.
captionPlatform -> DeviceNotificationSends ASR or TTS captions.
round_startPlatform -> DeviceNotificationMarks the start of one response audio round.
round_endPlatform -> DeviceNotificationMarks the end of one response audio round.
interruptDevice -> PlatformNotificationInterrupts the current platform response.
submit_speechDevice -> PlatformNotificationManually submits the current uplink speech.
update_configDevice -> PlatformRequestUpdates runtime session context. Currently only extra_params is supported.
device_actionPlatform -> DeviceRequestRequests the device to execute a declared capability.
end_sessionBothNotificationEnds the current session.

start_session

Direction: device -> Tange platform

The device must send start_session after the TiRTC connection is ready. The platform creates the session, loads device and role configuration, and returns the session ID and audio formats.

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
    }
  }
}

Required fields:

FieldRequiredDescription
device_idYesDevice ID.
role_idYesRole ID from role configuration or device-role binding.
input_audioNoUplink audio format. Uses platform defaults (usually pcm) when omitted. We highly recommend passing this explicitly to ensure the server and device have a consistent understanding and avoid compatibility issues.
output_audioNoDownlink audio format. Uses platform defaults (usually pcm) when omitted. We highly recommend passing this explicitly to ensure the server and device have a consistent understanding and avoid compatibility issues.

Both input_audio and output_audio contain:

FieldTypeDescription
codecstringAudio codec.
sample_rateintSample rate in Hz.
channelsintNumber of channels.

Supported Audio Formats

codecSupported sample rates (Hz)Supported channels
opus160001
pcm16000, 80001
g711a16000, 80001
amr8000 (NB), 16000 (WB)1

Notes:

  • The platform ASR / LLM / TTS pipeline runs at 16 kHz mono internally. Uplink audio that does not match the internal format is resampled on the platform side.
  • The actual session formats are defined by the input_audio and output_audio fields in the start_session success response. The device must send and decode audio according to those values.
  • Unsupported codec, sample rate, or channel combinations return a JSON-RPC error with message set to Invalid audio format.

Success response:

json
{
  "jsonrpc": "2.0",
  "id": "start-session-001",
  "result": {
    "session_id": "aivoice-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "input_audio": {
      "codec": "opus",
      "sample_rate": 16000,
      "channels": 1
    },
    "output_audio": {
      "codec": "opus",
      "sample_rate": 16000,
      "channels": 1
    }
  }
}

caption

Direction: Tange platform -> device

caption sends ASR or TTS text.

json
{
  "jsonrpc": "2.0",
  "method": "caption",
  "params": {
    "text": "Hello, how can I help?",
    "caption_type": 1,
    "is_final": true,
    "mode": 0,
    "utterance_id": 1001,
    "seq_num": 3,
    "begin_time_ms": 120,
    "end_time_ms": 1680
  }
}

params fields:

FieldAlways presentDescription
textYesCaption text.
caption_typeYesCaption source: 0 for ASR user caption, 1 for TTS reply caption.
is_finalYesWhether this is the final caption for the utterance.
modeYesDelivery mode: 0 for full text, 1 for incremental text.
utterance_idYesUtterance ID; captions from the same utterance share the same ID.
seq_numYesSequence number for ordering within the same utterance.
begin_time_msNoCaption segment start time in milliseconds; may be absent or 0.
end_time_msNoCaption segment end time in milliseconds; may be absent or 0.

Use caption_type + utterance_id as the caption group key. When mode=1, append text; when mode=0, replace the current text. Mark the group final when is_final=true.

round_start and round_end

Direction: Tange platform -> device

round_start marks the start of one response audio round:

json
{
  "jsonrpc": "2.0",
  "method": "round_start"
}

round_end marks the end:

json
{
  "jsonrpc": "2.0",
  "method": "round_end"
}

Use these events for UI state and playback state, but play audio according to the actual downlink audio stream.

interrupt

Direction: device -> Tange platform

json
{
  "jsonrpc": "2.0",
  "method": "interrupt"
}

The historical spelling interupt is also accepted by the platform and has the same effect as interrupt. New integrations should use interrupt.

After sending interrupt, the device should immediately stop playing buffered audio from the old response.

submit_speech

Direction: device -> Tange platform

submit_speech manually submits the current uplink speech. Typical scenarios include push-to-talk release, half-duplex talk, UI confirmation, or local device-side VAD deciding that the user has finished an utterance.

json
{
  "jsonrpc": "2.0",
  "method": "submit_speech"
}

Notes:

  • After submit_speech is sent, the platform treats the currently received uplink speech as submitted and continues the ASR / LLM / TTS flow.
  • submit_speech does not interrupt the current platform response. Use interrupt when the device needs to stop an in-progress response.
  • If the device relies only on cloud VAD to detect the end of speech, this event is usually not required.

update_config

Direction: device -> Tange platform

update_config updates small pieces of runtime context during an active session. Currently only extra_params is supported. It is intended for information such as location or business state that may change during the session. It does not update static settings such as welcome text, voice, or system prompt.

Request:

json
{
  "jsonrpc": "2.0",
  "id": "update-config-001",
  "method": "update_config",
  "params": {
    "extra_params": {
      "latitude": 39.9800718,
      "longitude": 116.309314
    }
  }
}

Success response:

json
{
  "jsonrpc": "2.0",
  "id": "update-config-001",
  "result": {
    "success": true,
    "message": "更新配置成功"
  }
}

Error response:

json
{
  "jsonrpc": "2.0",
  "id": "update-config-001",
  "error": {
    "code": -32602,
    "message": "update_config only supports extra_params, got \"voice\""
  }
}

Notes:

  • The response is a JSON-RPC response and does not include method: "config_updated".
  • Match the response to the update_config request by id.
  • Any field other than extra_params is rejected.

device_action

Direction: Tange platform -> device

When device capabilities are declared in the role configuration, the platform may send device_action to request the device to perform an action. This message is a JSON-RPC Request. The device must keep the id and return a response with the same id.

Request from platform:

json
{
  "jsonrpc": "2.0",
  "id": "device-action-001",
  "method": "device_action",
  "params": {
    "action": "set_light",
    "data": {
      "power": "on"
    }
  }
}

Success response from device:

json
{
  "jsonrpc": "2.0",
  "id": "device-action-001",
  "result": {
    "ok": true,
    "data": {
      "power": "on"
    }
  }
}

Error response from device:

json
{
  "jsonrpc": "2.0",
  "id": "device-action-001",
  "error": {
    "code": -32000,
    "message": "device is busy"
  }
}

end_session

Direction: both

end_session ends the current AI Chat session. It may be sent by the device or by the platform when the session should close.

Device to platform:

json
{
  "jsonrpc": "2.0",
  "method": "end_session"
}

Platform to device:

json
{
  "jsonrpc": "2.0",
  "method": "end_session"
}

After sending or receiving end_session, stop capture, stop playback, and release local session state. The cleanup flow should be idempotent.

Device Receive Example

c
#include <stdint.h>
#include <string.h>
#include "tiRTC.h"

#define TIRTC_AI_SIGNALING 0x2100

static void on_command(tirtc_conn_t hconn, uint32_t cmdw,
                       const void *data, uint32_t len)
{
    (void)hconn;
    if (cmdw != TIRTC_AI_SIGNALING || data == NULL || len == 0) {
        return;
    }

    /* data is a UTF-8 JSON-RPC string.
     * In production code, parse method / params with a JSON library,
     * then dispatch to caption, round_start, round_end, interrupt,
     * submit_speech, device_action, end_session, and other handlers. */
}

Self-Check List

  • Use the 0x2100 command word.
  • Ensure every payload is valid UTF-8 JSON.
  • Send start_session with an id, and handle both success and error responses.
  • Pass a valid role_id.
  • Handle incremental and full caption modes.
  • Handle round_start / round_end state changes.
  • Implement immediate local playback stop for interrupt.
  • If manual speech submission is needed, implement submit_speech.
  • If runtime config updates are needed, match the update_config JSON-RPC response by id.
  • If device capability calls are needed, handle device_action requests and responses by id.
  • Make end_session cleanup idempotent.

AI Chat