WebSocket based API to connect to Zello channels
Version 1.0
This document is intended for developers interested in implementation of their own Zello Channel API client connecting to Zello channels. If you want integrate Zello into your iOS or Android app, check out the mobile SDKs instead.
This API supports subset of Zello features and currently focused on sending and receiving channel voice messages. See Supported features for the complete list.
To access the API you need to generate a valid access token, based on JWT standard. See Authentication.
Service | WebSocket URL |
---|---|
Consumer Zello | wss://zello.io/ws |
ZelloWork | wss://zellowork.io/ws/network name |
Zello Enterprise Server | wss://your server domain /ws |
Note that the protocol only supports secure connections over TLS.
The API supports two types of accounts for both Zello and ZelloWork:
Anonymous accounts:
- No need to provide username or password
- Can access unrestricted channels in listen only mode
Named accounts:
- Must include a valid username and password
- Have full access to authorized channels
In both cases you need to provide a valid auth token.
This API uses persistent WebSocket connection with JSON-formatted WebSocket text messages for control protocol and WebSocket binary messages for voice data.
Each control request contains a command and an optional sequence number.
command
Command nameseq
Sequence number
A sequence number is required only if a response is expected. Both server and client maintain their own counters to ensure that unique sequence numbers are used with commands that include a sequence number.
Authenticates the client and connects to a channel. This must be the first command the client sends after establishing WebSocket connection. To stop the session and disconnect from the channel simply close the connection.
Name | Type | Value / Description |
---|---|---|
command |
string | logon |
seq |
integer | Command sequence number |
auth_token |
string | (optional) API authentication token. If omitted refresh_token is required. See Authentication |
refresh_token |
string | (optional) API refresh token. If omitted auth_token is required. See Authentication |
username |
string | (optional) Username to logon with. If not provided the client will connect anonymously. |
password |
string | (optional) Password to logon with. Required if username is provided. |
channel |
string | The name of the channel to connect to. |
listen_only |
boolean | (optional) Set to true to connect in listen-only mode. |
{
"command": "logon",
"seq": 1,
"auth_token": "[json web token]",
"username": "sherlock",
"password": "secret",
"channel": "Baker Street 221B"
}
{
"seq": 1,
"success": true,
"refresh_token": "[refresh json web token]"
}
or
{
"seq": 1,
"error": "error code"
}
Successful response includes refresh_token
which can be use to quickly reconnect if WebSocket connection is broken due to brief network interruption.
images_supported
flag indicates channel will accept images. texting_supported
flag indicates if channel will accept text messages.
After successfully connecting to the channel and receiving channel status you can start sending voice messages. Each message is sent as stream, which begins with start_stream
command followed by the sequence of binary packets with audio data and ends with stop_stream
command. Zello uses Opus voice codec to compress audio stream.
Starts a new stream to the channel. The successful response includes stream_id
which must be used in all data packets for this message as well as in stop_stream
command.
Name | Type | Value / Description |
---|---|---|
command |
string | start_stream |
seq |
integer | Command sequence number |
type |
string | Stream type. Only audio is currently supported |
codec |
string | The name of audio codec used. Required for audio streams. Must be opus . |
codec_header |
string | base64-encoded codec header buffer. Required for opus streams. |
packet_duration |
integer | Audio packet duration in milliseconds. Values between 2.5 ms and 60 ms are supported. |
for |
string | Optional username to send message to. Other users in the channel won't be receiving this message |
{
"command": "start_stream",
"seq": 2,
"type": "audio",
"codec": "opus",
"codec_header": "gD4BPA==",
"packet_duration": 20
}
or
{
"command": "start_stream",
"seq": 2,
"type": "audio",
"codec": "opus",
"codec_header": "gD4BPA==",
"packet_duration": 20,
"for": "Driver 2"
}
{
"seq": 2,
"success": true,
"stream_id": 22695
}
Stops outgoing stream. Send this command after you sent the last data packet.
Name | Type | Value / Description |
---|---|---|
command |
string | stop_stream |
stream_id |
integer | Stream ID as returned in response to start_stream command |
{
"command": "stop_stream",
"stream_id": 22695
}
The same packet structure is used for any streamed data (e.g. audio) travelling both ways. The packet ID field is only used with the audio packets sent from the server to a client. Fields are stored in network byte order.
{type(8) = 0x01, stream_id(32), packet_id(32), data[]}
After successfully connecting to the channel and receiving channel status you can start sending images.
If channel does not support image messaging you will receive an error for send_image
command.
Each image begins with send_image command followed by the sequence of binary packets with image thumbnail data and full image data.
Starts sending a new image to the channel. The successful response includes image_id
which must be used in all data packets for this image.
Name | Type | Value / Description |
---|---|---|
command |
string | send_image |
seq |
integer | Command sequence number |
type |
string | Image type. Only jpeg is currently supported |
thumbnail_content_length |
integer | Image thumbnail content length in bytes |
content_length |
integer | Full image content length in bytes |
width |
integer | Full image width in pixels |
height |
integer | Full image width in pixels |
source |
string | Image source (camera or library ) |
for |
string | Optional username to send image to. Other users in the channel won't be receiving this image |
{
"seq": 2,
"command": "send_image",
"type": "jpeg",
"source": "camera",
"width": 1279,
"height": 959,
"thumbnail_content_length": 10616,
"content_length": 183716
}
{
"seq": 2,
"success": true,
"image_id": 22695
}
{type(8) = 0x02, image_id(32), image_type(32) = 0x02, data[]}
{type(8) = 0x02, image_id(32), image_type(32) = 0x01, data[]}
After successfully connecting to the channel and receiving channel status you can start sending text images.
Sends a new text message to the channel.
Name | Type | Value / Description |
---|---|---|
command |
string | send_text_message |
seq |
integer | Command sequence number |
text |
string | Message text. 30 Kb maximum |
for |
string | Optional username to send text message to. Other users in the channel won't be receiving this text message |
{
"seq": 3,
"command": "send_text_message",
"text": "Hello Zello!"
}
{
"seq": 3,
"success": true
}
After successfully connecting to the channel and receiving channel status you can start sending locations.
Sends user's location to the channel.
Name | Type | Value / Description |
---|---|---|
command |
string | send_location |
seq |
integer | Command sequence number |
latitude |
number | Shared location latitude |
longitude |
number | Shared location longitude |
accuracy |
number | Shared location accuracy in meters |
formatted_address |
string | Shared location reverse geocoding result (street address) |
for |
string | Optional username to send location to. Other users in the channel won't be receiving this location data |
Indicates there was a change in channel status, which may include channel being connected/disconnected, number of online users changed, or supported features changed.
Name | Type | Value / Description |
---|---|---|
command |
string | on_channel_status |
channel |
string | The name of the channel |
status |
string | Channel status. Can be online or offline |
users_online |
integer | Number of users currently connected to the channel. |
images_supported |
boolean | Channel will accept image messages. |
texting_supported |
boolean | Channel will accept text messages. |
error |
string | Includes error description, when channel disconnected due to error. |
error_type |
string | unknown , configuration Indicates error type. When set to configuration indicates that current channel configuration doesn't allow connecting using the channel API credentials used. |
{
"command": "on_channel_status",
"channel": "test",
"status": "online",
"users_online": 2,
"images": true,
"texting": true
}
Indicates the start of the new incoming stream. This event corresponds to start_stream
command sent by another channel user.
Name | Type | Value / Description |
---|---|---|
command |
string | on_stream_start |
type |
string | Stream type. Only audio is currently supported |
codec |
string | The name of audio codec used. Required for audio streams. Must be opus |
codec_header |
string | base64-encoded codec header buffer. Required for opus streams |
packet_duration |
integer | Audio packet duration in milliseconds. Values between 2.5 ms and 60 ms are supported |
stream_id |
integer | The id of the stream that started |
channel |
string | The name of the channel |
from |
string | The username of the sender of the message |
{
"command": "on_stream_start",
"type": "audio",
"codec": "opus",
"codec_header": "gD4BPA==",
"packet_duration": 20,
"stream_id": 22695,
"channel": "test",
"from": "alex"
}
Indicates the stop of the incoming stream. This event corresponds to stop_stream
command sent by another channel user.
Name | Type | Value / Description |
---|---|---|
command |
string | on_stream_stop |
stream_id |
integer | The id of the stream that stopped |
{
"command": "on_stream_stop",
"stream_id": 22695
}
Indicates a server error.
Name | Type | Value / Description |
---|---|---|
command |
string | on_error |
error |
string | One of the error codes |
{
"command": "on_error",
"error": "server closed connection"
}
Indicates incoming image from the channel. This event corresponds to send_image
command sent by another channel user.
Name | Type | Value / Description |
---|---|---|
command |
string | on_image |
channel |
string | The name of the channel |
from |
string | The username of the sender of the image |
message_id |
integer | The id of the image message |
type |
string | image content type (jpeg ) |
height |
integer | Image height (some clients don't provide this value) |
width |
integer | Image width (some clients don't provide this value) |
source |
string | Image source (camera or library ) |
{
"command": "on_image",
"channel": "test",
"from":"alex",
"message_id": 59725,
"source": "camera",
"width": 591,
"height": 1280,
"ct": "jpeg"
}
on_image
event is followed by the sequence of two binary packets with image thumbnail data and full image data.
Fields are stored in network byte order similar to audio stream packets.
{type(8) = 0x02, message_id(32), image_type(32) = 0x02, data[]}
{type(8) = 0x02, message_id(32), image_type(32) = 0x01, data[]}
Indicates incoming text message from the channel.
Name | Type | Value / Description |
---|---|---|
command |
string | on_text_message |
channel |
string | The name of the channel |
from |
string | The username of the sender of the text message |
message_id |
integer | The id of the text message |
text |
string | Message text |
{
"command": "on_text_message",
"channel": "test",
"from": "alex",
"message_id": 16777216,
"text": "Hello Zello!"
}
Indicates incoming shared location from the channel.
Name | Type | Value / Description |
---|---|---|
command |
string | on_location |
channel |
string | The name of the channel |
from |
string | The username of the sender of the shared location |
message_id |
integer | The id of the shared location message |
latitude |
number | Shared location latitude |
longitude |
number | Shared location longitude |
formatted_address |
string | Shared location reverse geocoding result (street address) |
accuracy |
number | Shared location accuracy in meters |
{
"command": "on_location",
"channel": "test",
"from": "alex",
"message_id": 16777217,
"latitude": 30.27386375722625,
"longitude": -97.76014980128478,
"rgl": "1317 W 6th St, Austin"
}
Error Code | Description |
---|---|
unknown command | Server didn't recognize the command received from the client. |
internal server error | An internal error occured within the server. If the error persists please contact us at support@zello.com |
invalid json | The command received included malformed JSON |
invalid request | The server couldn't recognize command format. |
not authorized | Username, password or token are not valid. |
not logged in | Server received a command before successful logon . |
not enough params | The command doesn't include some of the required attributes. |
server closed connection | The connection to Zello network was closed. You can try re-connecting. |
channel is not ready | Channel you are trying to talk to is not yet connected. Wait for channel online status before sending a message |
listen only connection | The client tried to send a message over listen-only connection. |
failed to start stream | Unable to start the stream for unknown reason. You can try again later. |
failed to stop stream | Unable to stop the stream for unknown reason. This error is safe to ignore. |
failed to send data | An error occured while trying to send stream data packet. |
invalid audio packet | Malformed audio packet is received. |
Feature | Consumer Zello | ZelloWork |
---|---|---|
Access channels using authorized user credentials | Supported | Supported |
Access channels anonymously in listen only mode | Supported | Not supported |
Send and receive voice messages | Supported | Supported |
Interoperability with Zello apps on Android, iOS, and PC | Supported | Supported |
Create and access ad hoc channels anonymously | Planned | Planned |
Send and receive images | Planned | Planned |
Send and receive text messages | Planned | Planned |
Moderate Zello consumer channels | Planned | n/a |