Add a user to a group via API?

I’m trying to use the Discourse API to update a group with a particular user. In the docs that I have found, there wasn’t any information on this, only the ability to create a group.

I also tried to watch the XHR request when I’m actually updating a group on discourse with another user. The API seems to be calling this URL: groups/[group_name]/members.json, which I can call with a GET and get back the group info, but I get an error when I tried to PUT with the usernames parameter.

  "errors": [
    "You are not permitted to view the requested resource."
  "error_type": "invalid_access"

Any advice on how I can get around this? I have put my API key and username as a query as per the API documentation instructions.


Something similar to this will add users “bill” and “ben” to group “flower_pot_men”:

	 * Add users to a specified group, create the group if it doesn't exist.
	 * @param string $group_name name of group
	 * @param array  $usernames  users to add to group
	 * @return mixed HTTP return code and API return object

	public function add_users_to_group( $group_name, $usernames = array() ) {
		$group_id = null;

		$result = $this->get_request( "/admin/groups.json" );
		if ( $result->http_code != 200 ) {
			return $result;

		foreach ( $result->result as $group ) {
			if ( $group->name === $group_name ) {
				$group_id = $group->id;
			$group_id = false;

		if ( ! $group_id ) {
			$result = $this->post_request( '/admin/groups', array( 'name' => $group_name ) );
			if ( $result->http_code != 200 ) {
				return $result;
			$group_id = $result->result->basic_group->id;
		if ( ! empty( $usernames ) ) {
			$params = array(
				'usernames' => implode( ',', $usernames )
			$result = $this->put_request( '/admin/groups/' . $group_id . '/members.json', $params );

		return $result;
$group_name = 'flower_pot_men';
$usernames = array( 'bill', 'ben' );
$result = $api->add_users_to_group( $group_name, $usernames );
if ( $result->http_code != 200 ) {
	// @todo handle the error

EDIT: The key point here is the /admin part is different from yours.
EDIT #2: Updated to correctly reflect ID usage.

More about Bill and Ben



That’s the right approach. Discourse is very happy to reply with a 403 if anything isn’t as expected. I’ve been struggling with this too…

I recommend using a Proxy (if you’re using Windows, look at Fiddler) to carefully compare your request with a correct one from the web interface. Things to look at:

  • Are you really using PUT?
  • Do all parameters match 100%?
  • Do any relevant headers differ?

Also triple-check that you are really giving a correct API key and a valid username.

1 Like

Is the groupID supposed to be a number or the name of the group? From the API call I saw it was an ID. I actually get a 200 success when I use the ID, but the groups don’t seem to be updating for that user

Yes @jefflau you are correct it is a numeric group ID that is required.

I’ve updated the post above to reflect one method of implementing adding by name…
… specifically looks up the group ID by name, if not found create a group with that name…

… then add the users.

Managed to figure it out, but I used a completely different method:

addUserToGroup(userId, groupId){
    let url = `${this.url}admin/users/${userId}/groups`;
    let options = {
      params: {
        group_id: groupId
      query: this.defaultQuery
    return httpPromise('POST', url, options);

Uses post and uses a different url related to the user. Is there a difference to doing it one way or the other? I just couldn’t figure out what I was doing wrong with the other way.

Feel like someone should be keeping the API docs up to date. Shouldn’t have to go around fishing for what API calls work and what not!

1 Like

The docs are the live app, since the Discourse JavaScript app that you’re running right now makes those very same calls in the group management UI.

1 Like

This script will create a user and optionally add it to a group:


I’m getting 404 on PUT /admin/groups/{group_id}/owners.json on discourse 3.1.0.beta2 (f8863b0f98); is this topic up to date?

EDIT: it seems that one should use PUT /groups/{group_id}/owners.json instead. Additionally the input data is now {"members": "username1,username2,..."}.