Skip to content

Common frames

A few frames aren’t tied to one command. They report errors, sign-in results, and rate limits for any request. This page gives their exact shapes. The protocol model explains when each one is sent.

type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };
type Listener = JsonValue;

Any frame that answers a request carries the request’s listener, if it had one. Events never do.

A command failed.

{ "cmd": "error", "val": "Channel not found", "src": "messages_get", "listener": "history-1" }
interface ErrorFrame {
cmd: "error";
val: string;
src?: string;
listener?: Listener;
}
Field Description
val Text you can show. Schema failures use the form <path>: <message>, described in errors.
src The command that failed. Missing only for Invalid message format, when the frame couldn’t be parsed.

A sign-in attempt failed, or the server removed you. Sign-in commands (auth, login, register) use this instead of error.

{
"cmd": "auth_error",
"val": "Your join application is pending review",
"reason": "application_pending",
"mode": "application",
"application_id": "8c2e4a6b-0d1f-4e3a-9b5c-7d9e1f3a5b7c"
}
interface AuthErrorFrame {
cmd: "auth_error";
val: string;
reason?: string;
mode?: string;
application_id?: string;
listener?: Listener;
}
Field Description
val Text you can show.
reason A code for the failure. See the table below. Missing for failures such as a wrong password.
mode The server’s access mode. Present whenever access control turned you away.
application_id Your pending join application. Present only with reason: "application_pending".
reason Meaning
banned The account is banned from this server, or its Rotur account is banned.
kicked A moderator kicked you. val is Kicked: <reason>.
password_required, password_incorrect The server needs a password, and you sent none or the wrong one.
not_whitelisted The server is whitelist-only and you aren’t on the list.
application_required, application_pending The server needs an approved join application.
invite_required, invite_invalid, invite_expired The server needs a working invite code.

banned and kicked can also arrive without a request, and the server closes the socket right after. The full list of val strings is on auth.

An action was refused because of a timeout or slow mode, or a timeout changed.

{
"cmd": "rate_limit",
"reason": "Slow mode is active in this channel. Wait 4.2 more seconds before sending another message.",
"length": 4200,
"cooldown": 10,
"last_message_timestamp": 1788177595.8
}
interface RateLimitFrame {
cmd: "rate_limit";
length: number;
reason?: string;
src?: string;
cooldown?: number;
last_message_timestamp?: number;
listener?: Listener;
}
Field Description
length Time left, in milliseconds. 0 means a timeout has ended.
reason Text you can show.
src The refused command. Present when a timeout blocked a request.
cooldown Slow mode only: the channel’s delay between messages, in seconds.
last_message_timestamp Slow mode only: when you last posted in the channel, in Unix seconds.

A frame with cooldown is slow mode and applies only to that channel. A frame without it is an account timeout.

Sign-in worked. Other commands are now allowed.

{ "cmd": "auth_success", "val": "Authentication Successful" }

Follows auth_success with your account details.

interface ReadyFrame {
cmd: "ready";
user: User;
local_upload_token?: string;
rotur_token?: boolean;
listener?: Listener;
}
Field Description
user Your user object, including your own status.
local_upload_token Server accounts only. A 64-character token for HTTP uploads, valid while this connection is open.
rotur_token The server owner only. Whether the server has a Rotur API token configured.

Connection lifecycle lists the frames that can follow ready.