Skip to content
RESTful interface to ejabberd
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

mod_restful - RESTful API for ejabberd

How to enable

Add it to a HTTP listener, or add a new HTTP listener:

{listen, [
          {{8088, {127, 0, 0, 1}}, ejabberd_http,
           [{request_handlers, [{["api"], mod_restful}]}]}

This will open the port 8088 listening on connections only on localhost. Requests to http://hostname:8088/api/* will be handled by mod_restful.


The module itself is configured separately. Available options are

{api, [APISpec]}
  APISpec = {Path, Module, [ModuleOptions]}
  Path = [string()] % ["a", "b", "c"] represents a/b/c
  Module = module() % module responsible for requests
  ModuleOptions = any() % module specific options

An example configuration is shown here:

{modules, [
       {mod_restful, [
          {["admin"], mod_restful_admin, [
           {key, "secret"},
           {allowed_commands, [register, unregister]}
          {["register"], mod_restful_register, [{key, "secret"}]}

This enables two sub paths to two different mod_restful modules: mod_restful_admin under http://hostname:8088/api/admin and mod_restful_register under http://hostname:8088/api/register.


This module can be used for calling ejabberd commands remotely. Authorization of requests are by default done via HTTP Basic auth to authenticate a user with administrative privileges, or, if the key option is enabled, via a shared secret key.

Request descriptions are done via HTTP POST requests, with a JSON document describing the request. Two examples of running the command register follows.

To run a command, using admin@localhost:secret as basic authentication.

POST /api/admin HTTP/1.1
Authorization: Basic YWRtaW5AbG9jYWxob3N0OnNlY3JldAo==
Content-Type: application/json
Content-Length: 63


To run a command, using a shared secret key:

POST /api/admin HTTP/1.1
Content-Type: application/json
Content-Length: 78


When the request is authorized, the result of the command is converted to JSON. A reply from the server could look like this:

HTTP/1.1 200 OK
Content-Length: 54
Content-Type: application/json

{"ok":"User successfully registered"}

Available options:

{key, Key}
  Key = string() % secret key, used for authorization
{allowed_commands, [Command]}
  Command = module() % ejabberd_command command


Available options:

{key, Key}
  Key = string() % secret key, used for authorization

mod_restful_register is an interface to user registration. It provides a RESTful API registering new accounts, removing existing accounts, changing passwords of existing accounts, and checking availability of accounts.

Registration, removal and password changes are done with POST requests, while availability is a GET request. Using JSON, POST requests contain an object with keys and values. The following table describes required keys for each type of request.

  Request type    | Key          | Description
                  | username     | New username
  register        | host         | Hostname
                  | password     | New password
                  | email**      | Email address
                  | username     | Username to remove
  unregister      | host         | Hostname
                  | password     | Existing password, for authentication
                  | username     | Existing username
                  | host         | Hostname
  change_password | old_password | Old password, for authentication
                  | new_password | New password
  *               | key          | Key used for authorizing the request

 *  - the key can be used to all of the above
 ** - support activated via private_email configuration parameter

Possible responses are described in the following table.

  Request type    | Response      | Description
                  | ok                   | Registration was successful
  register        | email_not_set        | Registered without E-mail
                  | {error, exists}      | Username already exists
                  | {error, Error}       | Registration failed
                  | ok                   | Successfully unregistered
  unregister      | {error, not_exists}  | Username was not registered
                  | {error, net_allowed} | Password incorrect
                  | {error, Error}       | Unregistration failed
                  | ok                   | Password changed
  change_password | {error, not_allowed} | Old password was incorrect
                  | {error, Error}       | Changing password failed

In JSON the form would be either a string, or a map. ok would be "ok", and {error, not_allowed} would be {"error":"not_allowed"}.

An example session follows:

POST /api/register/register HTTP/1.1
Content-Type: application/json
Content-Length: 76


If the request was successful, a response looks like this:

HTTP/1.1 200 OK
Content-Length: 4
Content-Type: application/json


GET requests differ in that the parameters are provided in the URL. The available request is the is_registered request, which takes up to three parameters: key, username and host.

  Request type   | Key          | Description
  is_registered  | username     | New username
                 | host         | Hostname

Possible responses:

  Request type   | Response       | Description
                 | true           | Username is registered
  is_registered  | false          | Username is not registered
                 | {error, Error} | Some error occurred

Output follows the same rules as the one in the POST requests.

An example session follows:

GET /api/register/is_registered?username=test&

The response is either true or false (JSON encoded booleans). A response when the user exists is shown below.

HTTP/1.1 200 OK
Content-Length: 4
Content-Type: application/json


An optional feature is when registering is to pass an E-mail address. This feature is enabled by the option "private_email". When enabled registration will take an extra parameter "email" supplied via the JSON document. The E-mail address will be stored using mod_private_email ( If no E-mail, or an invalid E-mail is supplied, the register call will respond with the result "email_not_set". If an E-mail was successfully set, it will respond with a regular "ok" response.

Something went wrong with that request. Please try again.