Access via Discourse API, key and/or user rejected

As a moderator, I’d like to use the API for a discourse forum. Normally it was activated and I manage to get a API key. I used this script:

I manage to retrieve a key which is 32 characters long (is that right?), and in the security settings of my account, the app shows with these permissions:

Read all
Write all
Live updates
Push notifications to external services
Read and clear notifications
Read user session info
Create a one-time login token

That looks quite good. However, when I try to access through a script with:

from pydiscourse import DiscourseClient

client = DiscourseClient(


It is a python library, so I suppose it should work. The api_key has this specific format, it is not the actual key. I get the error that either the username or the api key are not valid.

Do I use my username or the app name?
Is the API key at least the right format, perhaps decrypting something went wrong?

If I use curl like here (Discourse-user-notes API - #4 by codetricity):

curl\ -H 'Api-Key: 388b79103056fede1d3223dae032df99'\ -H 'Api-Username: tflidd'

I get also an error:
{"errors":["You are not permitted to view the requested resource. The API username or key is invalid."],"error_type":"invalid_access"}

If I open the same URL with the json in my browser where I am logged in the web browser shows the right json object. So the topic exists and I have permissions to access it (this was even a public one).

I am just moderator, no direct admin access. I could ask for more info from the logs, if you have pointers what to look for.

In case it matters, the installed version is: 3.2.0.beta4-dev

The DiscourseClient python library is designed to work with an Admin API key (Admin → API).
What you generate from generate_api_key is a Client API key.

You need to pass API-User-Key and API-User-Username headers instead.
For example:

curl -H 'Api-User-Key: 388b79103056fede1d3223dae032df99' -H 'Api-User-Username: tflidd'`

:+1: this works, you don’t know how much time I spent on this.

But the API endpoints are the same described here

(if yes, it would be great to mention not only how to authenticate with the admin API key but also mention the client API key)

For the pydiscourse client, there is a hacky workaround to use a different header:

from pydiscourse import DiscourseClient

client = DiscourseClient(

headers = {
            "Accept": "application/json; charset=utf-8",
            "User-Api-Key": '388b79103056fede1d3223dae032df99',
            "User-Api-Username": 'tflidd',

slug = "abc"
topic_id = 1234

client.topic(slug=slug, topic_id=topic_id, override_request_kwargs=override_request_kwargs)
1 Like