Channel API and limits

The canonical reference for room.plugin channels, which exchange real-time data, covering functions, value formats, and save and sending limits.

Last updated October 19, 2026

On this page

A channel (room.plugin) is a pathway for exchanging data other than chat messages in real time, between people in the same chat room or between your server and a chat room. This page is the canonical reference for functions, value formats, and limits. For the overall flow, see Sending and receiving real-time data; for sending from a server, see Server REST API.

room.plugin

Name Description
room.plugin.add(channel) Returns a channel object. Calling it again with the same name returns the same object
room.plugin.TO_ALL 0. If the type of received data is this value, it was sent to everyone
room.plugin.ONLY_ME 1. If the type of received data is this value, it was sent to you only

Choose channel names that do not collide within the chat room. To use saving (save), the name must start with a letter or digit, contain only letters, digits, _, and -, and be 64 characters or fewer.

U.chat('*').on('after.create#dice', function (room) {
	if (room.id !== 'my-room') return;
	var ch = room.plugin.add('dice');
	ch.onReceived(function (room, data) {
		room.print(data.user.nick + ' rolled: ' + data.data[0]);
	});
	ch.addParser(function (args) {
		ch.send([Math.floor(Math.random() * 6) + 1]);
	});
});

Channel object

Function Arguments Description
send(values) Value array Sends to everyone in the chat room. You, the sender, receive it too
sendTo(nick, values) Nickname, value array Sends to one person only. You do not receive it unless you target your own nickname. If the target does not exist, nothing happens (no error)
save(values) Value array Saves the latest state on the server. Moderator or higher. See Saving below
clear() — Clears this channel's saved value. Moderator or higher
onReceived(fn) fn(room, data) Adds a receive callback. See Receiving below
addParser(fn) fn(args) Adds a callback that handles !channelname args input. See Command input handling below
destroy() — Removes the channel from the list. Registered callbacks are discarded too
  • The functions have no return value. Calls made before connecting are not sent. If the server rejects a call, an error event fires (permission 402, value error 101, limit 428).
  • Callbacks added with onReceived and addParser cannot be removed individually. Because add returns the same object, callbacks get mixed if your channel name collides with another script's. Use a unique name.

Value formats

Values you send are an array, and only the formats below are passed through as-is in each slot.

Value sent Value received
String String
Integer 0 or greater Number
Negative number, decimal Number
true, false true, false
undefined undefined (empty slot)
Object, array, null, function Dropped. The following values shift forward by one slot

For structured data, split it across slots or put it in a single string slot with JSON.stringify. Wrap JSON.parse of a received string in try.

ch.send(['move', 3, 5]);                                  // split across slots
ch.send(['state', JSON.stringify({ x: 3, y: 5 })]);       // one string slot

Receiving

The onReceived callback receives (room, data).

Key Description
data.user The sender's user object
data.type 0 (TO_ALL, send) or 1 (ONLY_ME, sendTo, targeted sends from the server, saved values)
data.data Value array
  • Sent by the server: Data sent through the REST API and saved values received again on join have data.user.auth set to 4 and an empty nickname. Check whether data came from the server only with data.user.auth === 4.
  • Saved values also arrive with auth 4, so auth 4 alone does not prove the REST API sent it. Only moderators or higher can write saved values.
  • Anyone can send other data. Do not trust it based on the nickname alone; validate the format and range of the values.
  • If before.plugin returns false, onReceived callbacks are not called (Events).

Command input handling

In the default skin, when someone types !channelname arg1 arg2 in the chat input, that channel's addParser callbacks are called with (['arg1', 'arg2']). Arguments are strings split on spaces. You can trigger the same handling from code with room.action.plugin('channelname', ['arg1']).

Case Result
No channel with that name room.action.plugin() returns false. The default skin sends the input as a normal message
before.plugin returns false false. Callbacks are not called
A callback returns false false. Later callbacks are not called, and the default skin sends the input as a normal message
Otherwise true. The input is not sent as a message

Parsers run only in your own browser. To let others know, call send inside the callback.

Saving

save(values) keeps the channel's latest state on the server. People who join later receive the saved value when they join (type 1, auth 4). It is not sent to people currently connected, so call send as well if needed.

Item Limit
Who can write Moderator or higher (otherwise error 402)
Saved value per channel Free rooms 1KB, paid rooms 4KB
Saved values for the whole room 60KB
Number of channels in a free room Effectively one. Saving to another channel clears the saved values of existing channels
Value formats Strings, numbers, booleans
  • The size of one channel is the number of UTF-8 bytes of the value array encoded as JSON. The 60KB total is the size of the entire { channel: value array } object, including channel names, encoded as JSON. If a limit is exceeded or the channel name does not follow the rules, the request is rejected with error 101.
  • In a free room, when the saved value is replaced by another channel's, the person who saved gets a control event (type: 'pluginDataReplaced').
  • Values saved with save live only in the chat server's memory. They may be lost when the chat room closes or the server restarts, and they are deleted when a paid room becomes free.
  • If you save from your server with "save": true in the Server REST API, the value is also kept on uchat servers, so it is read again the next time the chat room opens, even after the chat room closes or the server restarts. In this case it is also sent to people connected now, and the limits are the same as in the table above. Use this for values that must last (live status, scores, goal amounts, and so on).

Sending limits

Limit Details
Free room channel sending The total number of recipients over the last 60 seconds cannot exceed 100. Exceeding it gives error 428
Paid rooms No channel sending limit
Packet count When packets sent from the same IP per second (messages, commands, and channel sends combined) reach 10, you get error 425; going further disconnects you

Recipients are counted like this.

Send Deducted
send, REST API send to everyone Number of connected users at the time
sendTo, REST API targeted send 1
  • Deducted amounts come back after 60 seconds. For example, in a free room with 20 connected users, you can send up to 5 times per minute.
  • send and sendTo from page scripts share the same limit with REST API sends.
  • In a free room that has hit the limit, save is also rejected with error 428.

For state that changes often (positions, timers), do not send every time; batch updates, or send only when something changes.

Still not sure how it works? Ask your question on the contact board.

Business name UCHAT · CEO 김경욱 · Business registration no. 141-05-32832
Address 경기도 파주시 와석순환로 61 · Mail-order business registration no. 2013-경기파주-4485호
Phone 010-8677-8633 · Email support@uchat.io

ⓒ 2013–2026 UCHAT. All rights reserved.