Can't send PM via API (HTTPUnprocessableEntity 422)

Anyone know what I am doing wrong here please? It was working fine, then I don’t know what I did but it stopped working. I’ve stripped it back to this and it’s still not working:

irb> require 'uri'
=> true

irb> require 'net/http'
=> true

irb> Net::HTTP.post_form(URI.parse(""), {title: "test", raw: "test", archetype: "private_message", target_usernames: "Me"})

=> #<Net::HTTPUnprocessableEntity 422 Unprocessable Entity readbody=true>

I can’t even get this to work:


Any idea what’s going on?


This seems to be working again now - is there some kind of limit or temp bans if too many requests are sent within a specific time-frame? (I was testing so sending quite a few requests.)

…and it’s stopped working again :frowning:

All I did was add the following:

msg << "Here's the email template:"
msg << "\n \n"
msg << "Hi username!"
msg << "\n \n"
msg << "Guess what!? You won last month's giveaway :-)"
msg << "\n \n"
msg << "Please send me your:"
msg << "\n \n"
msg << "Full name:"
msg << "\n \n"
msg << "Email address:"
msg << "\n \n"
msg << "Country of residence:"
msg << "\n \n"
msg << "And I'll send your details over."
msg << "\n \n"
msg << "All the best,"
msg << "\n \n"
msg << "Aston"
msg << "\n \n"

The constructed msg is what’s sent as raw in the params.

1 Like

given it’s a 422, you are probably not hitting a rate limit.

Can you show the full code please ?

also I’ve been looking at Discourse API Documentation, where do you see the documentation to send private messages ? I only see a section on how to list private messages.

The full code is in the first post (use Ruby with IRB to run it).

Sam has said that PMs are just posts and it’s fine to use the API:


Ok I tried various things, and there’s definitely something weird going on. I tried sending a PM to me on (using the UI) while inspecting xhr requests, and sometimes I got 422 trying to do so.

I haven’t found a common pattern, the only thing I’m changing is the text sent, and it’s always over the char limit, and yet sometimes I get a 422.


anyway you can look at the response body and not just the status code? The response body should still return json with an “errors” section that could explain what is going on:


{"action":"create_post","errors":["Your error message here for a 422 status code"]}

also I think your your curl command is wrong because you aren’t specifying a POST request and/or your messages content isn’t url encoded.

Your curl command should be changed to look like this:

curl -X POST -d api_key="" -d api_username="discourse1" -d target_usernames="discourse2" -d archetype="private_message" -d title="my sample title" -d raw="This is a post to a topic." http://localhost:3000/posts

I thought about it later, and I’m pretty sure he is hitting a 422 while doing his tests because he is sending the same requests, so the content body of his 422 is probably “Body is too similar to what you recently posted”.

1 Like

I thought the same thing, and so I tried sending the same request over and over and it still returns a 200 with the same id (does not create a new pm).


Anyone else seeing random 422 errors in API calls?

I have gotten 422 errors when using postman to send PMs using the wrong API key. :slight_smile: I have to use the admin API key to get the expected 200 response.


Interesting, if that repros we should fix it @sam – bad / misleading errors are the worst.

1 Like

@blake can you review our api error statuses?


I am successfully able to create a PM just fine via the api as a user with a non-admin api key:

curl -i -sS -X POST "http://localhost:3000/posts.json" \
-H "Api-Key: 768dae6a45015f4220ad195ef9a8e8c4b48687a5b0bead26a6bbe2cf1a0f8b70" \
-H "Api-Username: steve" \
-F "title=I need to create a random title" \
-F "target_usernames=blake.erickson" \
-F "raw=This is the body of my pm that I am sending. I hope it is long enough" \
-F "archetype=private_message"

HTTP/1.1 200 OK

So far, all off the 422 responses that I was able to trigger have returned a json response in this format with an error message:

{"action":"create_post","errors":["Body is too similar to what you recently posted"]}

Some of the other error messages I was able to generate are:

One of the users you are sending this message to could not be found.

Title is too short (minimum is 2 characters)


Body is too short (minimum is 20 characters)","Body seems unclear, is it a complete sentence?

The “Body is too similar…” error will happen if a user sends the same pm to multiple different users, but an admin can successfully send the same pm body to multiple different users.

As long as we return an error message with the 422 I would say this endpoint is working as advertised.