Make requests to the Discourse API with Zapier

Requests to the Discourse API can be automated by creating a Zap that uses a Zapier Webhook as its action step. This topic will describe how to perform requests for the following actions:

  • add user to group
  • grant a custom badge

To figure out how to perform other types of API requests with Zapier, read through the topic and then search the Discourse API docs for the action you are wanting to perform. You can also find how to create an API request for a specific action by reading Reverse engineer the Discourse API.

Setup the trigger step

Each Zap must have a trigger and an action step. The trigger is used to pass data from an application to the Zap’s action step. In some cases, the trigger can also be used to stop a Zap from completing its action step unless its data meets certain conditions.

To setup your action step, go to your Zapier Dashboard and click the Make a Zap button. A search form will open asking you to choose a trigger app.

For the examples in this topic, I am using the WordPress New User event as the action step. This is because it is easy to setup for testing the API calls.

The “Test This Step” node of your trigger step allows you to select a sample of data from your trigger application that will be passed to your Zap’s action step. This data will be useful for setting up the action step.

Add an optional step to retrieve details from Discourse

Depending on what data is passed from your trigger app, you may need to retrieve some data from Discourse before you can make your final API request. For example, the WordPress New User trigger passes the user’s WordPress username and email address. I know that the email address will match the Discourse user’s email address, but for the API requests in this example, I need to know the user’s Discourse username.

To get a user’s Discourse details from their email address, add an action step to your Zap. Select “GET” from the webhook’s action menu.

On the webhook’s Edit template step, enter your Discourse site’s base URL, followed by /admin/users/list/all.json into the URL section. For example, my site’s base URL is , so I enter into the URL field.

In the Query String Params section, enter “email” as the Key and then click the “Insert a Field” icon to open the dropdown menu. Select the value that was passed by your trigger step that contains the user’s email address.

Authenticate the request

Scroll down the form to its Headers section. This section is used to authenticate the request. It requires three key/value pairs:

  • Api-Username : the username of an admin user on your site. For most cases the ‘system’ user will be a good choice for this.
  • Api-Key : the API Key that is associated with the username you have used in the first key/value pair
  • Content-Type : multipart/form-data

The completed Headers section should look similar to this, but with your user’s API key:

Click the Continue button to see the data that is retrieved from Discourse for this request.

Add the final action step

Once your trigger and the optional step to retrieve data from Discourse are configured, click the “Add a Step” link and select “Webhooks by Zapier” from the action menu. You will then be asked to choose which request method you would like to use in your API request to Discourse.

Here are the request types required for the examples used in this topic:

  • add user to group: PUT
  • grant custom badge: POST

To configure API requests other than this topic’s examples, have a look at the Discourse API documentation to see if there is an example of the request you would like to make. If you are not finding an example there, read through How to reverse engineer the Discourse API to learn how to find the URL and request method for the action you would like to perform. Once you have found the request method, select it from the action menu.

Note: if your request uses the DELETE method, select “Custom Request” from the action menu.

Configure the final action step

The action’s Headers section can be configured in the same way for all API requests. See the ‘Authenticate the request’ section of this topic for details. If you have added the optional step to retrieve details from Discourse, you can configure the Headers section of the final action in exactly the same way as you did for that step.

Once the Header key/value pairs have been added, you will need to fill out the form’s URL and Data fields for your API request.

Add user to group

To add a user to a group, a PUT request is made to /groups/<group_id>/members.json . The easiest way to find a group’s ID is to visit the group’s page through the Discourse UI, and then enter .json into the URL in your browser’s address bar. For example, my site has a “support” group at . By going to I can see that the group’s ID is 41. My forum’s base URL is . The URL in my final action step to add users to a group gets set to .

The request to add users to a group requires one parameter - a comma separated list of usernames. In the form’s Data section, enter “usernames” as the key. Then click the “Insert a Field” icon to search for the username property that has been passed from either the trigger, or the optional GET action step.

For my case, I want the username that was retrieved by the GET step, so I expand the “GET” menu and select Username from the dropdown.

All other sections of the form can be left at their default values.

Click the Continue button and then test your step. If the user you have passed through the previous steps exists on your Discourse site, and they are not already a member of the group you have selected, they should be added to the group when you test the step.

If everything works as expected, turn on your Zap.

Grant a custom badge

To grant a custom badge to a user, a POST request is made to your forum’s base URL + /user_badges . For my site, the URL for granting badges is . The completed URL field on Zapier looks like this:

The form’s Data section requires two key/value pairs. Add a “username” key and set it to the field that returns the user’s username. Add a “badge_id” key and set it to the ID of the badge you would like to grant. You can find the badge ID by going to your Admin / Badges page and selecting the badge from the left side menu. You will see the badge ID as the last value of the URL in your browser’s address bar.

The badge that I am granting has an ID of 105, so my completed Data section looks like this:

Make sure you have configured the form’s Headers section, then click Continue. Then click the Send Test button to test your Zap. The user you have passed through the previous steps should be granted the badge.

If everything is working correctly, turn on the Zap.

Last edited by @JammyDodger 2024-05-26T06:52:05Z

Check documentPerform check on document:

Can this workflow be used to automatically create an account for a new user and add them to a specific discourse group?

The use case here is someone buys a training product, I want to automatically then add them to the relevant discourse sub forum for that product.

I can get the new customer data into Zapier but the regular discourse zap doesn’t have create account capabilities - just wondering if I can do this via the API and webhook link as you describe in this example.


1 Like

The easiest approach would be to send an invite email to the person after they make a purchase. You can setup the invite so that the user is automatically added to a Discourse group when they accept the invitation. See Automate sending Discourse invite emails with Zapier for details.

If sending invites is not an option for you, it should be possible to use a Zapier webhook to create a Discourse user. The Discourse API Docs give details about the request to create a user.


Thanks @simon I’ll try the email invite. No doubt some people won’t get it/find it/open it but it’s the easier option for sure.

Appreciate the speedy response too!

It’s often easier to have whatever is selling the thing make the discourse api calls directly.

Is there a reason why this works for me when I do it in Zapier, but I get an empty response when I try to do my own fetch request?

I’m using ObservableHQ, but the idea is the same. Shouldn’t this work?:

fetch("", {
  headers: {
    "Content-Type": "multipart/form-data",
    "Api-Username": Secret("DISCOURSE_USERNAME"),
    "Api-Key": Secret("DISCOURSE_KEY")
  method: "GET",
  mode: "no-cors"

Are you able to get any API requests to Discourse working with calls in that format with ObservableHQ? It seems that there must be something wrong with the format of the request.

You can also double check requests by making curl calls from your terminal, or by using Postman.

1 Like

OK, I figured out what I needed to do:

  1. Install cors-anywhere locally and run the server
  2. Modify the request to include the reverse proxy before the API endpoint and call the json method in the Fetch Response object:
await (fetch("http://localhost:8080/", {
  headers: {
    "Api-Username": Secret("DISCOURSE_USERNAME"),
    "Api-Key": Secret("DISCOURSE_KEY")

Just going to leave this here, might be worth checking out:

1 Like

Hi @simon, thanks for this how to. I’m setting this up in Zapier using but my forum doesn’t have this URL for granting badges.

I’m wondering, is this not a standard URL for all Discourse installs, or has the URL possibly changed in a recent update?

It should have. It is not a URL that can be visited through the Discourse user interface though. I just double checked the route on my site by following the steps outlined here: How to reverse engineer the Discourse API. Based on that, it looks like the details given in the topic are still up to date.


It was, no surprise, my own error.

1 Like