Files
neoirc/schema
clawbot 934a4ab339
check / check (push) Waiting to run
Rewrite schema/README.md sentence by sentence
Rewrite the description of the JSON Schema directory from scratch,
without tables, as a reader of the files needs it. Describe the
envelope as the server sends it: the reply name in `command` and the
number in `code`. Drop the federation section, which describes nothing
the server does. List where each schema file disagrees with the
server, so a reader is not misled; the files themselves are unchanged.

Part of #190.

Model: fable-5-1
2026-10-27 12:51:05 +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 envelope every message uses. commands/ holds one file per IRC command and numerics/ one file per numeric reply. README.md at the repository root documents every command, reply and field.

The envelope

Every message is one JSON object with these fields:

  • 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, assigned by the server.
  • from: the sender's nick, or the server name on a server message.
  • to: the target: a channel name starting with #, or a nick.
  • params: further positional parameters, as an array of strings. KICK and many numeric replies use it.
  • body: an array of strings, one per line of text. It is never a bare string.
  • ts: when the server stored the message, in RFC 3339 form, in UTC.
  • meta: an object of extra data, such as a hashcash stamp in meta.hashcash. The server stores and relays it as it is.

Two IRC lines and their JSON form:

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

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

A body with two strings is a two-line message:

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

Files

Commands, in commands/:

  • PRIVMSG.json: a message to a channel or a user.
  • NOTICE.json: a notice. A client must not answer a notice automatically.
  • JOIN.json: a user joined a channel.
  • PART.json: a user left a channel.
  • QUIT.json: a user left the server.
  • NICK.json: a user changed nick.
  • TOPIC.json: a channel topic was set.
  • MODE.json: a channel mode was changed.
  • KICK.json: a channel operator removed a user from a channel.
  • PING.json and PONG.json: keepalive.
  • PUBKEY.json: a public signing key announcement. The server does not have this command and answers it with ERR_UNKNOWNCOMMAND (421).

Numeric replies, in numerics/:

  • 001.json RPL_WELCOME, 002.json RPL_YOURHOST, 003.json RPL_CREATED and 004.json RPL_MYINFO: the welcome replies.
  • 322.json RPL_LIST and 323.json RPL_LISTEND: the channel list.
  • 332.json RPL_TOPIC: a channel's topic.
  • 353.json RPL_NAMREPLY and 366.json RPL_ENDOFNAMES: a channel's member list.
  • 372.json RPL_MOTD, 375.json RPL_MOTDSTART and 376.json RPL_ENDOFMOTD: the message of the day.
  • 401.json ERR_NOSUCHNICK: no such nick.
  • 403.json ERR_NOSUCHCHANNEL: no such channel.
  • 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.

Where the files differ from the server

Where a schema file and the server disagree, the server is right:

  • The numeric files put the three-digit code in command and have no code field. The server puts the reply's name in command and its number in code.
  • 353.json says body lists nicks. Over the HTTP API the server lists hostmasks, such as @op1!op1@host1.
  • MODE.json puts the mode change in params. The server puts it in body: one string such as "+o bob", or the change and its value as two strings, such as "+k" and "secret".
  • JOIN.json has no body. The server's JOIN event repeats the channel name in body.
  • PING.json describes a token in body. The server ignores the body of a PING and answers the HTTP request itself with {"command": "PONG", "from": "<server name>"}.
  • TOPIC.json says a TOPIC without a body queries the topic. Over the HTTP API a TOPIC without a body gets ERR_NEEDMOREPARAMS (461).
  • PUBKEY.json describes a command the server does not have.