Tip of the day: Use set::restrict-commands to prevent new users from executing certain commands like LIST. Useful against drones/spam.

JSON-RPC:Technical documentation

From UnrealIRCd documentation wiki
Jump to navigation Jump to search

This is the technical documentation for JSON-RPC for developers and people who want to interact with UnrealIRCd via the JSON-RPC API. It assumes you have read and configured your UnrealIRCd according to the JSON-RPC article.

We start with the PHP library, followed by a general introduction on how to connect to the JSON-RPC interface using the transports that are available (domain sockets, HTTPS POST and websockets) and the JSON-RPC protocol. We end with listing the 40+ JSON-RPC Methods (API calls).

PHP library

This wiki page talks about all the inner details of JSON-RPC. But, if you use PHP then it makes more sense to use our library at https://github.com/unrealircd/unrealircd-rpc-php that already does all the work for you.

This PHP library is also used by the webpanel, it allows easy interfacing with UnrealIRCd through regular PHP code, such as:

use UnrealIRCd\Connection;

$api_login = 'api:apiPASSWORD'; // same as in the rpc-user block in UnrealIRCd

$rpc = new UnrealIRCd\Connection("wss://",

$bans = $rpc->serverban()->getAll();
foreach ($bans as $ban)
    echo "There's a $ban->type on $ban->name\n";

$users = $rpc->user()->getAll();
foreach ($users as $user)
    echo "User $user->name\n";

$channels = $rpc->channel()->getAll();
foreach ($channels as $channel)
    echo "Channel $channel->name ($channel->num_users user[s])\n";

Sadly, our PHP library is currently lacking documentation, so the other info on this page could still be of help. Or just to get a better understanding of all the functionality and inner details.


You can issue JSON-RPC requests to UnrealIRCd using: UNIX domain sockets, HTTPS POST or Websockets.

UNIX domain socket

This is for local connections only. On the server side you have this:

listen {
        file "/home/xyz/unrealircd/data/rpc.socket";
        options { rpc; }

NOTE: UnrealIRCd 6.0.6+ has this listen block by default when rpc.modules.default.conf is included.

Then simply connect to the socket and you can issue JSON-RPC requests directly. Example:

$ nc -U ~/unrealircd/data/rpc.sock
{"jsonrpc": "2.0", "method": "channel.list", "params": {}, "id": 123}
{"jsonrpc": "2.0", "method": "channel.list", "id": 123, "response": {"list": []}}

There is no authentication being done, as only local users can use this and the socket is only readable/writable by the user running UnrealIRCd by default (rwx------).

Each request should end with a newline (an enter). You can issue multiple requests (even in parallel, no need to wait for the response). The connection is not closed.

The connection is only closed if some fatal JSON parsing error is encountered such as a missing }. Normally that should never happen. Other errors such as an unknown method being called, invalid parameter count, etc. are not fatal: you will get an error back but the connection will not be closed.


On the server side this requires you to open up a port (Listen block) and add at least one api user (Rpc-user block):

listen {
        ip *;
        port 8600;
        options { rpc; }

rpc-user apiuser {
        match { ip 192.168.*; }
        password "password";

Then do a POST request to /api with the JSON request. The user and password (apiuser:password) are used as Basic Authorization. You must do this over https.


curl -s --insecure -X POST -d '{"jsonrpc": "2.0", "method": "channel.list", "params": {}, "id": 123}' https://apiuser:[email protected]:8600/api

The connection is closed after processing the request. If you want to issue another API call then do a new HTTPS POST. If you want streaming requests/responses, use HTTPS Websocket (see next section).

HTTPS Websocket

On the server side the config is the same as for HTTPS POST. You open up a port (Listen block) and add at least one api user (Rpc-user block):

listen {
        ip *;
        port 8600;
        options { rpc; }

rpc-user apiuser {
        match { ip 192.168.*; }
        password "password";

Now make a HTTPS websocket connection (not HTTP!) to https://localhost:8600/ and:

  • Add a header with "Authorization" type "Basic" that includes your user:pass, so apiuser:password in this case. We do it like this in the unrealircd-rpc-php library.
  • Naturally, localhost will never have a valid TLS certificate so you may need to disable certificate checking. If you use the websocket over the internet to a real host like irc1.example.org then you better keep TLS certificate checks enabled, of course!

Once the websocket connection is established you can send JSON requests. Each request goes into its own websocket frame, eg:

{"jsonrpc": "2.0", "method": "channel.list", "params": {}, "id": 123}

The connection is kept open so you can issue more JSON-RPC requests. You may also send multiple requests in parallel (each in their own websocket frame), you don't have to wait for a response. Every response will be in their own websocket frame as well. We use the websocket frame type "text" and not "binary".

The connection is only closed upon:

  • A fatal error, such as a JSON parsing error. Obviously this should never happen.
  • When the client does not respond to a websocket PING in time (as required by the websocket specification). Note that browsers automatically PONG back upon PING, so you don't have to worry about it there.

JSON-RPC Protocol

The JSON request/responses that UnrealIRCd uses follow the JSON-RPC 2.0 specification.


This is an example query. It calls the channel.list method with empty parameters:

{"jsonrpc": "2.0", "method": "channel.list", "params": {}, "id": 123}


If succesful, UnrealIRCd will reply with a response object. Here's an example if there are 0 channels:

{"jsonrpc": "2.0", "method": "channel.list", "id": 123, "response": {"list": []}}

The response will naturally be different for each method. And as you can see, the id is included so the client application can track request/responses.


A request may also result in an error instead of a response object. Here's an example error object that UnrealIRCd may send:

{"jsonrpc": "2.0", "method": "qwerty", "id": 123, "error": {"code": -32601, "message": "Unsupported method"}}

Error codes:

// Official JSON-RPC error codes:
JSON_RPC_ERROR_PARSE_ERROR              = -32700, /**< JSON parse error (fatal) */
JSON_RPC_ERROR_INVALID_REQUEST          = -32600, /**< Invalid JSON-RPC Request */
JSON_RPC_ERROR_METHOD_NOT_FOUND         = -32601, /**< Method not found */
JSON_RPC_ERROR_INVALID_PARAMS           = -32602, /**< Method parameters invalid */
JSON_RPC_ERROR_INTERNAL_ERROR           = -32603, /**< Internal server error */

// UnrealIRCd JSON-RPC server specific error codes:
JSON_RPC_ERROR_API_CALL_DENIED          = -32000, /**< The api user does not have enough permissions to do this call */
JSON_RPC_ERROR_SERVER_GONE              = -32001, /**< The request was forwarded to a remote server, but this server went gone while processing the request */
JSON_RPC_ERROR_TIMEOUT                  = -32002, /**< The request was forwarded to a remote server, but the request/response timed out (15 seconds) */
JSON_RPC_ERROR_REMOTE_SERVER_NO_RPC     = -32003, /**< The request was going to be forwarded to a remote server, but the remote server does not support JSON-RPC */

// UnrealIRCd specific application error codes:
JSON_RPC_ERROR_NOT_FOUND                =  -1000, /**< Target not found (no such nick / channel / ..) */
JSON_RPC_ERROR_ALREADY_EXISTS           =  -1001, /**< Resource already exists by that name (eg on nickchange request, a gline, etc) */
JSON_RPC_ERROR_INVALID_NAME             =  -1002, /**< Name is not permitted (eg: nick, channel, ..) */
JSON_RPC_ERROR_USERNOTINCHANNEL         =  -1003, /**< The user is not in the channel */
JSON_RPC_ERROR_TOO_MANY_ENTRIES         =  -1004, /**< Too many entries (eg: banlist, ..) */
JSON_RPC_ERROR_DENIED                   =  -1005, /**< Permission denied for user (unrelated to api user permissions) */

JSON-RPC Methods