Using the APIs



This topic is a linked part of a larger work: “Discourse Admin Manual


1. About API access to

2. Obtaining an API key

3. Accessing ethical consent data

4. Accessing codes

5. Accessing annotations

1. About API access to

1.1. API Overview

All relevant information in the database is accessible via APIs. We support the following APIs:

  • public Discourse API: This API gives access to everything that can be viewed as non-logged-in visitor on No API key or user account is required. For the API documentation, see

  • protected Discourse API: All Discourse content that can only be viewed with a user account requires an API key to access it. See below on how to get an API key for your user account. It will give you access to what your user has access to. For example, access to some protected categories, while a moderator user’s API key is required for example to get access to user e-mail addresses etc… For the API documentation, again see

  • protected custom API: This API is custom-made for and gives access to “secondary content” (the codes and annotations of Open Ethnographer), and to the user records of our “ethical consent” form. Access requires a normal Discourse API key of a Discourse moderator or admin user.

API access that uses an API key is throttled to avoid server overload. The current limits per API key are 30 API requests per minute and 10,000 API requests per day, and can be looked up (by admins) here.

1.2. Python library

We wrote a small Python module containing a collection of functions to fetch Edgeryders content,consent data and Open Ethnographer codes and annotations via API:

2. Obtaining an API key

You do not need an API key for the public Discourse API, see above. If you do need an API key, ask @alberto or @matthias (or another Discourse admin) to create one for you. You can not create it yourself, and you should save it somewhere because you can not look it up in your Discourse account later.

For Discourse admins, this is how you create API keys:

  1. Go to “Admin → Users” and select the target user.
  2. Scroll down to find “Permissions” and under it “API key”.
  3. Click the Generate Key button.
  4. Tell the user their API key via a secure channel (for example, encrypted Matrix chat).

3. Accessing ethical consent data

The Edgeryders platform has a feature called an ethical consent funnel. This serves to users trying to post for the first time a popup form that we call the “consent funnel”: it asks users to answer some questions before they are able to post in certain categories (resp. in Drupal, challenges). They can only proceed past the form when they have answered its questions correctly. This file contains the wording of the questions. When a user answers the questions correctly, the platform updates the value of a field called edgeryders_consent. The GitHub issue asking for the implementation of this feature is here.

We interpret this sequence of events as having given informed consent to participating in a research project with Edgeryders, and having understood the nature of their part in the exercise.

This feature was only fully implemented in July 2017. It follows that many of the earlier users of Edgeryders have not been through it. So, the interpretation of the edgeryders_consent field is as follows:

  • 'edgeryders_consent' = '1': user has given consent. Includes valid consent given on the Drupal platform that was later imported (with the consent timestamp reflecting the import time so far).
  • 'edgeryders_consent' = NULL: user has not gone through the consent funnel. (The value is not really NULL, but a logical equivalent: the record in table user_custom_field will simply be missing for this user and name = edgeryders_consent).

In the Fall 2017 we attempted to elicit consensus from 191 users that had contributed to opencare before 2017 (but never after). After this experience, we created two new values for the edgeryders_consent field:

  • 'edgeryders_consent' = '0': user was re-contacted after contributing to Edgeryders pre-July 2017, and has denied consent.
  • 'edgeryders_consent' = 'no answer': user user was re-contacted after contributing to Edgeryders pre-July 2017, but failed to answer after repeated attempts.
  • 'edgeryders_consent' = 'unreachable': user user was re-contacted after contributing to Edgeryders pre-July 2017, but the e-mail they used to create the Edgeryders account is no longer active.

4. Accessing codes

The Open Ethnographer codes endpoint is accessible at

A standard response looks like this:

    id: 13,
    name: "accessible laboratories",
    description: null,
    creator_id: 3323,
    created_at: "2017-09-05T16:09:52.870Z",
    updated_at: "2017-09-05T16:09:52.870Z",
    ancestry: null

Open Ethnographer supports code hierarchies. The ancestry field returns the parent code of the code at hand.

Codes can be filtered by creator like this:

You can request info about a single code with its ID like this:

5. Accessing annotations

The annotations endpoint is accessible at

A standard response looks like this:

    id: 5579,
    version: "v1.0",
     text: null,
    quote: "comfortable for the patient.",
    uri: "/post/33751",
    created_at: "2017-05-22T19:13:10.000Z",
    updated_at: "2017-05-22T19:13:10.000Z",
    code_id: 342,
    post_id: 33751,
    creator_id: 3323

Fields have been named in such a way that their meaning is self-evident. The one exception is text: this is a comment field that ethnographer can use to explain their thinking behind the annotation.

The following GET parameters can be used to filter annotations in the response:

  • topic_id: Return annotations which belong to the given topic.
  • post_id: Return annotations which belong to the given post.
  • creator_id: Return annotations which were created by the given user.
  • discourse_tag: Return annotations which are tagged with the given Discourse tag. The tag’s name, rather than the tag’s ID, needs to be passed in. A list of available discourse tags can be found here:
  • code_id: Return annotations which are tagged with the given Open Ethnographer code.

Filter parameters can be combined as needed. E.g. to return all annotations that belong to a certain topic and were created by a specific user:

The output is paginated. By default, one page contains at most 100 annotations. This can be changed with the per_page GET parameter:

If there are more annotations available than the given per_page limit they can be accessed on subsequent pages by using the page GET parameter:

If no further annotations are available, an empty array is returned for that page.

:green_book: Discourse Admin Manual
:green_book: Open Ethnographer Manual