Create a Discourse user from a Zapier request

I’m trying to create an active user with the API.

This works from curl:

curl -X POST "" -H "Api-Key: $API_KEY" -H "Api-Username: system" -H "Content-Type: multipart/form-data" -F "name=XXXXApp Tester" -F "" -F "username=XXXapptester21" -F "active=true" -F "approved=true" -F "password=simplepass"

When I do the same call from Zapier (I see that the Parameters in production.log look the same), it has this in the logs:

Filter chain halted as :respond_to_suspicious_request rendered or redirected

And nothing happens.

Is there some way around this?

  def suspicious?(params)
    return false if current_user && is_api? && current_user.admin?
    honeypot_or_challenge_fails?(params) || SiteSetting.invite_only?

I’m guessing it’s failing on is_api?. Looking at the code, it’s not obvious to me why that would fail with the request from Zapier, but I can’t see anywhere else it would fail.

I’m interested in this because someone was asking me about the same issue with creating users via Zapier a few weeks ago.


My other thought is that Zapier isn’t passing the API key correctly, but I think I’d get a different error.

I’m guesing it’s the same person. :slight_smile:


Yup. I am surprised this is not working but at least now I know it’s not just me.

I am looking at this approach of using an external DB and an automation tool like Zapier or Make (I was getting similar errors on make) as a POC for a pilot program.

I can get away without using one of these tools in the short term pilot phase but longer term Discourse will be one part of a larger platform and I definitely need to manage members in an external DB in a separate back end with member management and other services.

1 Like

I suspect the issue is related to how you are structuring the request on Zapier. Using the Webhooks by Zapier action, try this:

Select “POST” as the Event. Then:

URL: <>

Payload Type: “json”


  • name: <user’s full name> (shown as required in the docs, but should be ok to omit)
  • username: the user’s username
  • email: the user’s email
  • password: some password that meets your site’s requirement
  • active: "true" (in quotes)
  • approved: "true" (in quotes)

Fill in the Headers section to add your Api-Key and Api-Username (I’ve only tried this with system as the Api-Username.

Use the default values for all other sections.

Here are a couple screenshots with fake data:

That’s working for me. If it’s not working, the other thing to check is to make sure the invite only setting isn’t enabled on your Discourse site.

To see if it would work, I also just made a custom integration with the Zapier CLI that creates new users. If Discourse want, that action could be added to the official Discourse Zap. I’m not sure that adding an action to create users is a priority though. I don’t think it’s been requested as often as things like creating an invite or suspending a user.

Notes from further testing:

  • the Payload Type can be set to either “json” or “form”. To set custom fields with the request, the payload type needs to be set to “form”.

  • Multiselect custom fields are a bit of an issue. Zapier won’t allow duplicate key names in the Data section. It should be possible to set Multiselect custom fields with the Zapier “Custom Request” action.

  • the values of the active and approved parameters do not need to be wrapped in quotation marks.


@simon Thanks! I got it to work! Your screenshot helped me sort out the issues with the way Zapier is creating the data fields. It was doing some wonky stuff but I was basically not understanding how to format / map the data to airtable. I need to get the end to end automation working but the create user definitely worked.

fyi @pfaffman


Hi @simon - thanks again for the help on the formatting. Now I am trying to add some custom fields to the user profile and see if I can get Zapier to populate them in a new Discourse user. It seems to be causing the whole request to fail and I am getting a message “you have not completed all the user fields”

I found this post so I tried switching it to form from json but that didn’t work

Any advice on how to format custom profile fields? Thanks!

1 Like

Changing the payload type to “form” works for me:


Except that approach won’t work with multiselect dropdown fields. For that type of field I think you’ll have to use the “Custom Request” action. Might take a bit of fiddling around to get it to work.

1 Like

Wow - you are truly the grand wizard of zapier + discourse. Changing the red arrow and it worked first try. I had it as the name of the field but of course that makes no sense given would not know that upstream. So for every new field I create I just use the [#] and it will automatically map them in order? I am planning a bunch - maybe 10 or so. Also, it seemed to work fine even though my test field is a drop down - maybe because it’s just pulling it from Airtable?

1 Like

Actually - I did not do a real end to end test. I just tested the zap but it did work on a drop down field.

Yes, just put the field’s id in the []. You can get the id of the field by loading the JSON version of your Admin / Customize / User Fields page (/admin/customize/user_fields.json)

(It’s easier to read if you have a browser extension that formats JSON.)

Drop down fields should be fine. It’s just Multi-select fields that will have issues. For example, the “hobbies” field in the screenshot I posted above.

1 Like

Ah multiselect - yeah I missed that part. I only have single select drop down for now.

This is awesome. Thanks!!!

1 Like

Wonder whether it’s ok to open this one up again and ask about creating groups?

  • I can create users from Zapier without an issue (even when invite only is turned on) :white_check_mark:

The Zapier interface allows for individual API headers but when it asks for an object (which creating a group appears to require) … I get this, even if I edit the body manually to be formatted like the API docs ask:

Failed to create a custom actions in Discourse

Raw request failed. Problem executing your request: Error code 400: param is missing or the value is empty: group

Is there a way I can send that initial object group { and close it again using Zaiper?

Any insight would be amazing and much appreciated!

I solved it - I had to use Zapier’s Webhooks in the fully customised mode so that I could enter all the headers manually as well.

Then I just pasted in the data/body area and it worked … it just would not work in any other mode.