Getting ["BAD CSRF"] when updating topic via API [python]

Hey folks, I am having issues updating a topic. I am able to get the id of the first post as shown here. This is confirmed by running the following:

import requests
from requests.structures import CaseInsensitiveDict

url = "https://my/discourse/instance/posts/{post_id}.json"

headers = CaseInsensitiveDict()
headers["Authorization"] = "{"api-key": "{le_api_key}", "api-username": "{le_username}"}"

resp = requests.get(url, headers=headers)

print(resp.status_code)

Which returns a 200 status code and the info I expected about the post.

But when I try:

import requests
from requests.structures import CaseInsensitiveDict

url = "https://my/discourse/instance/posts/{post_id}.json"

headers = CaseInsensitiveDict()
headers["Authorization"] = "{"api-key": "le_api_key", "api-username": "le_username"}"
headers["Content-Type"] = "application/json"

data = """
{
  "post": {
      "raw": "Cool post, but here's an updated to the post's body",
      "edit_reason": "I changed this because I can."
   }
}
"""

resp = requests.put(url, headers=headers, data=data)

print(resp.status_code)

I get
["BAD CSRF"]

I am an admin and my key is global. Ideally I would like to run this with a less permissive key.
This post is the first and only in a topic a created via the API.

Thank you so much in advance :slight_smile:

Why are you nesting the headers under this Authorization dict key? That is not documented at Discourse API Documentation :thinking:

2 Likes

You are right, that’s something the tool I am using to test the API is doing and it works and that’s a problem on itself apparently:

header1 = CaseInsensitiveDict()
header1["Authorization"] = '{"api-key": "longapikey", "api-username": "myusername"}'

header2 = {"api-key": "longapikey", "api-username": "myusername"}

r = requests.get(url, headers= HEADER)

When HEADER == header1, it works, when == header2, I get:

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

Thanks for your reply btw!