Files
neoirc/schema
sneak 83a3245d5d
check / check (push) Waiting to run
Make the schema files match the server (closes #218)
Each file in schema/ now describes what the HTTP API on next sends and
accepts. A numeric reply has its name in command and its number in code.
body is always an array of strings. MODE, KICK and JOIN carry their
values in body, and TOPIC needs a non-empty body. PING takes no token,
and its PONG is the HTTP response. A channel name is limited to 63
characters, and the leading # is optional from a client.

PUBKEY.json is deleted, since the server has no such command. The
section of schema/README.md that listed the differences is removed,
and the sentences it made false are corrected.

Model: opus-5-5
2026-11-02 04:47:22 +00:00
..

Message schemas

This directory holds JSON Schema files (draft 2020-12) for the messages that the neoirc HTTP API carries. message.json describes the fields that every message can have. commands/ has files for some commands. numerics/ has files for some of the numeric replies. A numeric reply is a server reply named by a three-digit number, such as 001. README.md at the repository root documents the protocol.

The server can also run an IRC listener for ordinary IRC clients. The IRC listener sends plain IRC lines, which these files do not describe.

Message fields

Every message is one JSON object, which message.json calls the envelope. These are the fields it can have:

  • command: the IRC command name, such as PRIVMSG, or the name of a numeric reply, such as RPL_WELCOME. Always present.
  • code: the number of a numeric reply, such as 1 for RPL_WELCOME. Absent on other messages.
  • id: the message's UUID, a unique ID that the server assigns.
  • from: the sender's nick, or the server name on a numeric reply or a PONG.
  • to: the target, such as a channel name starting with # or a nick.
  • params: an array of strings with the message's other parameters, in order. KICK events and many numeric replies have it. The HTTP API ignores params sent by a client.
  • body: an array of strings. It is never a bare string. In a PRIVMSG or NOTICE, each string is one line of text.
  • ts: the time the server stored the message. It is an RFC 3339 time in UTC, such as 2026-10-27T12:00:00.123Z.
  • meta: an object of extra data, such as a hashcash stamp in meta.hashcash. A hashcash stamp is a short string that takes a computer some work to make. A PRIVMSG to a channel with mode +H needs one. The HTTP API relays the meta of a PRIVMSG or NOTICE unchanged. It drops the meta of every other command.

Here is one PRIVMSG as the IRC listener sends it and as the HTTP API sends it. The JSON leaves out id, ts and meta:

IRC:  :alice!alice@* PRIVMSG #general :hello world
JSON: {"command": "PRIVMSG", "from": "alice", "to": "#general", "body": ["hello world"]}

In the JSON, a numeric reply has its name in command and its number in code. This 353 reply lists the members of #general. The JSON again leaves out id, ts and meta:

{"command": "RPL_NAMREPLY", "code": 353, "from": "neoirc", "to": "alice",
 "params": ["=", "#general"], "body": ["@op1!op1@host1 alice!alice@host2"]}

A PRIVMSG whose body has two strings is a two-line message:

{"command": "PRIVMSG", "to": "#general", "body": ["line one", "line two"]}

Files

Most command files describe both the message a client sends and the message the server sends. Their field descriptions say where the two differ. The examples in the files leave out id, ts and meta.

Commands, in commands/:

  • PRIVMSG.json: a message to a channel or a user.
  • NOTICE.json: a notice, which is a message that a client must not answer automatically.
  • JOIN.json: joining a channel.
  • PART.json: leaving a channel.
  • QUIT.json: leaving the server.
  • NICK.json: changing nick.
  • TOPIC.json: setting a channel's topic.
  • MODE.json: querying or changing a channel's modes or the user's own modes.
  • KICK.json: a channel operator removing a user from a channel.
  • PING.json: a check that the server still answers.
  • PONG.json: the answer to a PING, which is the HTTP response to it.

Numeric replies, in numerics/:

  • 001.json: RPL_WELCOME, which welcomes the user.
  • 002.json: RPL_YOURHOST, the server's name and version.
  • 003.json: RPL_CREATED, the date the server last started.
  • 004.json: RPL_MYINFO, the server's name, its version and its lists of modes.
  • 322.json: RPL_LIST, one channel in the answer to LIST.
  • 323.json: RPL_LISTEND, the end of the answer to LIST.
  • 332.json: RPL_TOPIC, a channel's topic.
  • 353.json: RPL_NAMREPLY, a channel's members.
  • 366.json: RPL_ENDOFNAMES, the end of the member list.
  • 372.json: RPL_MOTD, one line of the message of the day.
  • 375.json: RPL_MOTDSTART, the start of the message of the day.
  • 376.json: RPL_ENDOFMOTD, the end of the message of the day.
  • 401.json: ERR_NOSUCHNICK, the nick does not exist.
  • 403.json: ERR_NOSUCHCHANNEL, the channel does not exist.
  • 433.json: ERR_NICKNAMEINUSE, the nick is taken.
  • 442.json: ERR_NOTONCHANNEL, the user is not on that channel.
  • 482.json: ERR_CHANOPRIVSNEEDED, the user is not a channel operator.