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
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 asPRIVMSG, or the name of a numeric reply, such asRPL_WELCOME. Always present.code: the number of a numeric reply, such as1forRPL_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 aPONG.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.KICKevents and many numeric replies have it. The HTTP API ignoresparamssent by a client.body: an array of strings. It is never a bare string. In aPRIVMSGorNOTICE, each string is one line of text.ts: the time the server stored the message. It is an RFC 3339 time in UTC, such as2026-10-27T12:00:00.123Z.meta: an object of extra data, such as a hashcash stamp inmeta.hashcash. A hashcash stamp is a short string that takes a computer some work to make. APRIVMSGto a channel with mode+Hneeds one. The HTTP API relays themetaof aPRIVMSGorNOTICEunchanged. It drops themetaof 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 aPING, 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 toLIST.323.json:RPL_LISTEND, the end of the answer toLIST.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.