Private Message Send API

Is it possible to send a private message through the API?

It appears you may only view direct (private) messages, not create them. The API repository @ GitHub shows only viewing abilities (GET).

Why do you want to create a private message via API? What is your scenario for wanting this feature?

1 Like

You can create them. URL structure is sorta like this:,username2

Send a private message and with Chrome developer tools watch the Network tab. (You can learn a lot of neat functionality doing that.)


The API key can be used via URL? That doesn’t sound safe.

The API + curl allows something to be posted at the server level, bypassing the client/browser layer, which is safer than exposing the API key via html link. Someone only needs to check the dev tools as you did and grab it.

However, this depends on what exactly @Stackfish wants this for.

A PM is just a type of post, you can create a PM just fine using the API. In fact we are using the API on this very site to create PMs.

PM stands for personal message by the way


But via URL or curl? A URL would expose the API key, correct?

Via Discourse api gem or curl or whatever.

1 Like

Only if it’s transported over unsecured HTTP, in which case an intercepting observer could have grabbed the form data anyways.

1 Like

@AdamCapriola Thanks that’s a cool trick and that should meet my needs.

@purldator The reason I’m looking into this is that we are using Discourse as the forum for a larger community. We would like to use discourse as the primary mechanism for messaging and alerts within in our community.

For example, it would be really cool if Stackfish could send a notification (or private message) every time one of our user’s gets a buddy request or one of their stories in liked. These notifications would be system generated.

Thanks to everyone!

1 Like

Is this a POST or a GET? I tried sending this as a GET and I receive a 200 response but no message is created. Does this still work?

I just needed to send the request as a POST

Sorry I haven’t gotten around to implementing this yet so I’m not sure.

Hi Adam! Trust all is well with you.

Do you know if there a way to auto archive messages sent via API? Or if not, could such an option be added to the API @codinghorror?

We are getting alot of these API generated messages and we only need to see them when they are replied to, which would put them back in the inbox. For now we are manually selecting all and archiving them. It would be nice to skip that manual step.

Since you are creating private message via API call, you could also change the topic status:

It looks like status=archived and enabled=true sets the archived flag.

1 Like

awesome! Thanks for looking into this. I tried it though, and unless I’m getting something wrong I think this is not working for personal messages - maybe the statuses work differently for messages than topics?

I’m sorry to hear that! I’ve been looking into the APIs for a similar purpose - feeding private messages into the system and managing them. It sounds like there are some bugs that might make this difficult - did you report that status changes didn’t work on PMs?

Hi Brian! I don’t think this is a bug necessarily - more that I am not understanding the difference between messages and topics. Unlike topics, which can be archived for everyone, messages have an inbox and an archive for each user (and for each group) included in the message. So there’s likely another field for tracking that for each user.

I had a quick dig in the data explorer and indeed see there are user_archived_messages and group_archived_messages tables but don’t really know what that means or how they work, or if it’s actually possible via the API to place an outgoing message in the sender’s archive or a group’s archive by default but in the inbox for the intended recipient.

Anyhoo this is not the highest priority for me as I have found a workflow with the current setup that seems to work for my team. If you do figure it out, let me know! :slight_smile:


What if you use an email template as a message?

I am going to the email_templates endpoint, grabbing the template I want, then send that as a private message. However, none of the strings are replaced in the message to the user. The message contains %{site_name} and ${base_url} inside the message text.

Just wondering how/when in the flow does Discourse substitute these (I couldn’t find any evidence).

Swapped out the api_key and site name, entered it into Chrome and got a 406 error. I assume I am applying it wrong (sorry not a programmer)? :confused:

I’m attempting to send a PM through the API. (This is intended for a game in which each player is dealt a hand of cards, so it does need to be private.)

I’m sending a request with appropriate values for raw, title and target_usernames, and getting back {"action":"create_post","errors":["Category can't be blank"]} with a 422 Unprocessable Entity.

If I set a category, it ignores target_usernames and creates a topic in that category.

If someone is successfully creating and sending PMs using the API, could you post an example with your full request body schema?

1 Like