# Changing Category Permissions via API

**URL:** https://meta.discourse.org/t/changing-category-permissions-via-api/42735
**Category:** Support
**Created:** [April 18, 2016, 5:04pm UTC](https://meta.discourse.org/t/changing-category-permissions-via-api/42735 "2016-04-18T17:04:43Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Marcos\_Conceicao](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/marcos_conceicao/32/121818_2.png) [@Marcos\_Conceicao](https://meta.discourse.org/u/Marcos_Conceicao)
#### Post date: [April 18, 2016, 5:04pm UTC](https://meta.discourse.org/t/changing-category-permissions-via-api/42735/1 "2016-04-18T17:04:43Z")

</div>

I’m trying to change a category permission via API, but returning error 400.

I created this function with the php api.

 ![](https://global.discourse-cdn.com/meta/original/3X/d/d/dddd0580af9badd7b029ad36bf32ee782e6975b0.png)

And calling on my script:  
$r = $api-\>editCategoryPermissions(641, array(‘admins’ =\> 1));

But returning error 400.

Can anyone help me?

---

<div class="post-metadata">

### Author: ![DeanMarkTaylor](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/deanmarktaylor/32/102462_2.png) [@DeanMarkTaylor](https://meta.discourse.org/u/DeanMarkTaylor)
#### Post date: [April 18, 2016, 5:32pm UTC](https://meta.discourse.org/t/changing-category-permissions-via-api/42735/2 "2016-04-18T17:32:14Z")

</div>

Probably call with something more like:

```php
$r = $api->editCategoryPermissions(641, array(
  array('group_name' => 'admins', 'permission_type' => 1)
));

```

---

<div class="post-metadata">

### Author: ![Marcos\_Conceicao](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/marcos_conceicao/32/121818_2.png) [@Marcos\_Conceicao](https://meta.discourse.org/u/Marcos_Conceicao)
#### Post date: [April 18, 2016, 5:57pm UTC](https://meta.discourse.org/t/changing-category-permissions-via-api/42735/3 "2016-04-18T17:57:15Z")

</div>

Still giving error 400.

---

<div class="post-metadata">

### Author: ![DeanMarkTaylor](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/deanmarktaylor/32/102462_2.png) [@DeanMarkTaylor](https://meta.discourse.org/u/DeanMarkTaylor)
#### Post date: [April 18, 2016, 6:17pm UTC](https://meta.discourse.org/t/changing-category-permissions-via-api/42735/4 "2016-04-18T18:17:42Z")

</div>

OK, this will likely be due to array handling for parameters in PHP:

Change the function to:

```php
function editCategoryPermissions( $categoryId, $permissions, $username = 'system' ) {
  $params = array();
  foreach ( $permissions as $group => $permission ) {
    $params['permissions[' . $group . ']'] = $permission;
  }

  if ( empty( $params ) ) {
    // @todo consider throwing an exception here
    // sending empty parameters is most likely bad
  }
  return $this->_putRequest( '/categories/' . $categoryId, $params, $username );
}

```

And call as you did before:

```php
$r = $api->editCategoryPermissions( 641, array( 'admins' => 1 ) );

```

---

<div class="post-metadata">

### Author: ![Marcos\_Conceicao](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/marcos_conceicao/32/121818_2.png) [@Marcos\_Conceicao](https://meta.discourse.org/u/Marcos_Conceicao)
#### Post date: [April 18, 2016, 6:56pm UTC](https://meta.discourse.org/t/changing-category-permissions-via-api/42735/5 "2016-04-18T18:56:16Z")

</div>

Thanks @DeanMarkTaylor, but still throwing 400

---

<div class="post-metadata">

### Author: ![DeanMarkTaylor](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/deanmarktaylor/32/102462_2.png) [@DeanMarkTaylor](https://meta.discourse.org/u/DeanMarkTaylor)
#### Post date: [April 18, 2016, 6:58pm UTC](https://meta.discourse.org/t/changing-category-permissions-via-api/42735/6 "2016-04-18T18:58:19Z")

</div>

What does the body text of the 400 error say?

What does the implementation of `_putRequest` look like?

---

<div class="post-metadata">

### Author: ![Marcos\_Conceicao](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/marcos_conceicao/32/121818_2.png) [@Marcos\_Conceicao](https://meta.discourse.org/u/Marcos_Conceicao)
#### Post date: [April 18, 2016, 7:07pm UTC](https://meta.discourse.org/t/changing-category-permissions-via-api/42735/7 "2016-04-18T19:07:09Z")

</div>

> [@DeanMarkTaylor](#):
>
> What does the body text of the 400 error say?

Nothing 😕

```php
stdClass Object ( [http_code] => 400 [apiresult] => )

```

> [@DeanMarkTaylor](#):
>
> What does the implementation of `_putRequest` look like?

```php
private function _putRequest($reqString, $paramArray, $apiUser = 'system')
    {
        return $this->_putpostRequest($reqString, $paramArray, $apiUser, true);
    }

private function _putpostRequest($reqString, $paramArray, $apiUser = 'system', $putMethod = false)
    {
        $ch = curl_init();
        $url = sprintf(
            '%s://%s%s?api_key=%s&api_username=%s',
            $this->_protocol, 
            $this->_dcHostname, 
            $reqString, 
            $this->_apiKey, 
            $apiUser
        );
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($paramArray));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if ($putMethod) {
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
        }
        $body = curl_exec($ch);
        $rc = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        $resObj = new \stdClass();
        $resObj->http_code = $rc;
        $resObj->apiresult = json_decode($body);
        return $resObj;
    }

```

---

<div class="post-metadata">

### Author: ![DeanMarkTaylor](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/deanmarktaylor/32/102462_2.png) [@DeanMarkTaylor](https://meta.discourse.org/u/DeanMarkTaylor)
#### Post date: [April 18, 2016, 7:34pm UTC](https://meta.discourse.org/t/changing-category-permissions-via-api/42735/8 "2016-04-18T19:34:46Z")

</div>

Personally I always:

1. get the existing properties for the category from Discourse first
2. reduce the result properties down to a known whitelist of properties
3. add the permissions
4. then make the `PUT` request

It might be that one or more of the of the properties is required.

The category permissions editor built into Discourse follows a similar process, however it knows exactly what should be sent back without needing a whitelist.

Filtering by a whitelist could be risky if other properties are added (by a new version of Discourse, a plugin, or custom fields), I haven’t checked the Discourse code to see if it removes the property if not set.
