REST2

From Request Tracker Wiki
Jump to navigation Jump to search

RT REST2 (JSON) API

  • RT has two REST APIs - the original REST v1.0 API and a newer, REST2 JSON API.
  • The REST1 API is still used and supported. Many things use it, including RT's mail gateway, rt-mailgate.

The REST2 API uses JSON for queries and responses, making it easier to integrate RT with other systems to read and update RT from scripts and applications on remote servers.

Releases

  • REST2 is core in RT 5.0.0 and later, so you do not need the extension for those versions.

Authentication Tokens

  • It is recommended to use authentication tokens instead of usernames and passwords for API requests, especially when used in scripts and automation. Authentication should always be done over HTTPS/SSL for security. You should only serve up the /REST/2.0/ endpoint over SSL.
  • Authentication Tokens is core in RT 5.0.0 and later, so you do not need the extension for those versions.
  • If upgrading from RT 4.4.x to RT 5.0.x and later: A clean install is recommended anyway. If you were using RT::Authen::Token. You will need to remove any configuration for RT::Authen::Token and follow the migration steps to migrate your existing tokens to RT5 core.

Documentation and Examples

There are some differences between RT5 core REST2 and earlier RT::Extension::REST2. Refer to the correct documentation for the RT version you are using:

Unfortunately the documentation lacks detailed explanation and examples in many places, especially for anything other than tickets (users, groups etc.).

The purpose of this wiki page is to collect working examples, code snippets and other resources to help work with the API.

Other sources of help

If you can't find an answer:

  • Ask in the RT forums for help.
  • Try asking ChatGPT or AI tools, referring to the above OpenAPI spec and Documentation.
  • Consider alternatives such as the PERL or REST1 APIs.
  • Hire Best Practical to develop a solution. :)


Examples

RT System Information

  • A good start to check it's working and authenticating correctly:
curl -s -X GET \
-H "Authorization: token <your_token>" \
-H "Accept: application/json" \
"https://<your_server>/REST/2.0/rt"

Returns similar to:

{
  "Version" : "5.0.7",
  "Plugins" : [
     "RT::Extension::BooleanCustomField",
     "RT::Extension::CustomFieldsOnUpdate",
     "RT::Extension::NonWatcherRecipients",
     "RT::Extension::Tags",
     "RT::Authen::OAuth2",
     "RT::Extension::CommandByMail",
     "RT::Extension::RepliesToResolved",
     "RT::Extension::TicketLocking",
     "RTx::Calendar"
  ]
}
  • Plugins list will only be present if the user has SuperUser privileges in RT.

Create New User

curl "https://<your_server>/REST/2.0/user" \
   --request POST \
   --header "Authorization: token $RT_TOKEN" \
   --header "Content-Type: application/json" \
   --no-buffer \
   --data-binary '
       {
           "Name": "newuser2",
           "Password": "password123",
           "EmailAddress": "newuser2@example.com",
           "RealName": "New User",
           "Privileged": 1,
       }'
  • Omitting Privileged will add an unprivileged user by default.

Search for group by name

  • This example searches for a group "Staff" and returns the details:
curl --silent "https://<your_server>/REST/2.0/groups" \
   --request POST \
   --header "Authorization: token <your_token>" \
   --header "Content-Type: application/json" \
   --data-binary '
       [
           { "field": "Name",
             "value": "Staff"
            }
       ]'

Response:

{
  "pages": 1,
  "items": [
    {
      "_url": "https://<your_server>/REST/2.0/group/71414",
      "type": "group",
      "id": "71414"
    }
  ],
  "per_page": 20,
  "total": 1,
  "count": 1,
  "page": 1
}

Add User to Group

# Add a user to a group, where group_id is set in a variable, and user name is set in a variable rt_user: 
curl --silent "https://<your_server>/REST/2.0/user/$rt_user/groups" \
   --request PUT \
   --header "Authorization: token <your_token>" \
   --header "Content-Type: application/json" \
   --data-binary '['$group_id']'
  • Working with JSON data structures in bash is fiddly. You can use jq to get values from the JSON in a useable format. For example by piping the above Search for group by name curl example to return various properties from the search for group "Staff", e.g.:
$ curl ... <as above> | jq -r '.items[].id'
71414
  • If you are doing anything serious, it is better to use a scripting language such as python or perl, which has support for JSON and nested data structures. But by way of example, I have posted a simple example of a bash script to add a user to a group using the REST2 API: rt-groupadd

Get only user defined groups

  • The groups query returns all groups by default, including internal groups (e.g. role groups for tickets.) This can return many thousands groups, which is unhelpful. The output also doesn't contain the group's name or type. To return only User Defined groups (e.g actual groups users are added to in RT.):
curl  https://<your_server>/REST/2.0/groups --request POST \
   --header "Authorization: token <your_token>" \
   --no-buffer \
   --data-binary '
       [
           { "field": "Domain",
             "value": "UserDefined"
            }
       ]'
  • You can also add fields= parameter to the url to include otherwise hidden fields:
curl https://<your_server>/REST/2.0/groups?fields=Name,Description,Domain,CustomFields --request POST \
   --header "Authorization: token <your_token>" \
   --no-buffer \
   --data-binary '
       [
           { "field": "Domain",
             "value": "UserDefined"
            }
       ]'

Search for user by Email Address

curl https://<your_server>/REST/2.0/users \
   --request POST \
   --header "Authorization: token <your_token>" \
   --header "Content-Type: application/json" \
   --data-binary '
       [
           { "field": "EmailAddress",
             "value": "newuser@example.com"
            }
       ]'

Returns:

{
  "page" : 1,
  "count" : 1,
  "total" : 1,
  "per_page" : 20,
  "items" : [
     {
        "id" : "newuser",
        "type" : "user",
        "_url" : "https://<your_server>/REST/2.0/user/newuser"
     }
  ],
  "pages" : 1
}
  • Oddly, the id returned here is the username, not the numeric id as might be expected. Users can be retrieved using either id or username, so it's not always necessary to get the user id. If you actually want the numeric id, add it to fields=:
curl https://<your_server>/REST/2.0/users?fields=id,Name \
   --request POST \
   --header "Authorization: token <your_token>" \
   --header "Content-Type: application/json" \
   --data-binary '
       [
           { "field": "EmailAddress",
             "value": "newuser@example.com"
            }
       ]'

Returns:

{
  "items" : [
     {
        "type" : "user",
        "id" : 118176,
        "_url" : "https://<your_server>/REST/2.0/user/newuser",
        "Name" : "newuser"
     }
  ],
  "per_page" : 20,
  "total" : 1,
  "pages" : 1,
  "page" : 1,
  "count" : 1
}
  • Notice the value of id is now the numeric id but as username is not included by default it is gone. Include Name in fields parameter to get it back if this is a wanted field, or you need a consistent field which does not change between username and numeric id.

Search Users by Partial Email Address

  • Find all users with email address domain example.com.
  • This example adds the Email address and a few more useful fields to the results:
curl https://<your_server>/REST/2.0/users?fields=id,Name,EmailAddress,RealName,Organization\
   --request POST \
   --header "Authorization: token <your_server>" \
   --header "Content-Type: application/json" \
   --data-binary '
       [
           { "field": "EmailAddress",
             "operator": "ENDSWITH",
             "value": "@example.com"
            }
       ]'

Returns:

{
  "pages" : 1,
  "total" : 2,
  "per_page" : 20,
  "items" : [
     {
        "RealName" : "Freddy Farquar",
        "Name" : "newuser",
        "id" : 118176,
        "type" : "user",
        "_url" : "https://<your_server>/REST/2.0/user/newuser",
        "EmailAddress" : "newuser@example.com",
        "Organization" : "Acme Widgets Ltd"
     },
     {
        "RealName" : "John Doe",
        "Name" : "newuser2",
        "EmailAddress" : "newuser2@example.com",
        "Organization" : "Acme Widgets Inc",
        "type" : "user",
        "id" : 118178,
        "_url" : "https://<your_server>/REST/2.0/user/newuser2"
     }
  ],
  "page" : 1,
  "count" : 2
}
  • Note: Only enabled users are retuned by default. You can add "&find_disabled_rows=1" to the URL show disabled users, but there appears to be no way to include the "Disabled" field, or to search on it e.g. "find only disabled users".
  • It also doesn't seem possible to search for Privileged users?

Clients for RT REST2 API

OpenAPI Documentation Generator

  • The following example installs and runs openapi-generator on Debian to create documentation based on Colloquial's OpenAPI Specification. There are a number of other ways to install it (see documentation). This was the quickest way for me to install it on my existing RT dev server:

1. Create html directory e.g. /var/www/apidocs and configure your web server to serve this directory from a suitable URL. (optional):

# mkdir /var/www/apidocs

2. nginx config snippet (goes in the relevent server section). restart nginx after adding:

       # REST2 API Docs
       location /apidocs {
               alias /var/www/apidocs;
       }

4. Install:

 # apt-get install pip default-jre
 # pip install openapi-generator-cli

5. Generate docs from yaml, e.g:

 # root@support:~# cd /var/www/apidocs
 # root@support:/var/www/apidocs# wget https://gitlab-ext.utu.fi/rt/request-tracker-openapi/-/raw/main/request_tracker_rest2.yaml
 # root@support:/var/www/apidocs# openapi-generator-cli generate -g html2 -i https://<your_server>/apidocs/request_tracker_rest2.yaml

6. Browse to your documentation location e.g. https://<your_server>/apidocs