> ## Client identification
>
> Requests to this API should include a `Client-Platform` header alongside
> `Authorization`, identifying the application, tool, or model making the
> request. This is used for integration support and analytics.
>
> Use your model or tool name, for example `claude-code` or `chatgpt`.
>
> Example:
>
> ```bash
> curl https://api.salaryboxapp.com/... \
>   -H "Authorization: Api-Key <api-key>" \
>   -H "Client-Platform: claude-code"
> ```

# Set Staff Permissions

PUT https://api.salaryboxapp.com/v2/customer/v1/staff/{salarybox_id}/permissions
Content-Type: application/json

Sets the permissions of a staff member on the Custom role. Shared rules: see [Writing Data](/writing-data).

- This replaces everything: the staff member ends up with exactly the permissions you send, and `[]` removes all.
- Read the current set first from Fetch Single Staff (`permissions` field), change it, and send the full list.
- Only an Admin key can call this endpoint.
- The staff member must have the Custom role first. Use Set Staff Role to change it.
- Every `:edit` permission (and `reimbursement_request:approve`) needs its `:view` permission in the same list.
- Get the valid names, and what each one requires, from List Available Permissions (`GET /staff/permissions`). They are also on the [Staff Permissions](/staff-permissions) page.


Reference: https://docs.salarybox.in/api-reference/staff/permissions-set

## Authentication

- `Authorization` header (required) (prefixed with ` Api-Key   `) — Format: "Api-Key \{api-key}"

## Request

### Path parameters

- `salarybox_id` (string, required) — SalaryBox ID of the staff member.

### Body (application/json)

This endpoint expects a StaffPermissionsSetRequest.

- `permissions` (list of enum, required) — Complete list of permissions the Custom-role staff member should have. `[]` removes all. Every `:edit` permission (and `reimbursement_request:approve`) also needs its `:view` permission in the list.
  - Allowed values: `attendance_record:view`, `attendance_record:edit`, `attendance_report:view`, `attendance_report:edit`, `work_schedule:view`, `work_schedule:edit`, `attendance_mode:view`, `attendance_mode:edit`, `attendance_automation_rule:view`, `attendance_automation_rule:edit`, `leave_request:approve`, `leave_balance_policy:view`, `leave_balance_policy:edit`, `reimbursement_request:view`, `reimbursement_request:edit`, `reimbursement_request:approve`, `staff_details:view`, `staff_details:edit`, `staff_documents:view`, `staff_documents:edit`, `additional_settings:view`, `additional_settings:edit`, `face_enrolment:view`, `face_enrolment:edit`, `staff_salary:view`, `staff_salary:edit`, `penalty_overtime:view`, `penalty_overtime:edit`, `tax_declaration:view`, `tax_declaration:edit`, `bank_account:view`, `bank_account:edit`, `leave_approval_flow:view`, `leave_approval_flow:edit`, `reimbursement_approval_flow:view`, `reimbursement_approval_flow:edit`

## Response

### 200

The permissions were replaced. `data.permissions` is the resulting set, sorted alphabetically.

- `message` (string, required)
- `status` (boolean, required)
- `data` (StaffPermissionsSetResponseData, required)

## Errors

### 400 Bad Request Error

Validation failed, the staff member is inactive, or the staff member does not have the Custom role.

- `message` (string, required)
- `status` (boolean, required)
- `errors` (map from string to any, optional, nullable)

### 403 Forbidden Error

The key owner may not make this change. Either the user who created the API key is no longer active, has been deleted, is no longer in the company, or no longer has the Admin or Custom role; or the key owner is not an Admin.

- `message` (string, required)
- `status` (boolean, required)
- `errors` (map from string to any, optional, nullable)

### 404 Not Found Error

No eligible active staff member with this `salarybox_id` exists in your company.

- `message` (string, required)
- `status` (boolean, required)
- `errors` (map from string to any, optional, nullable)

## Types

### StaffPermissionsSetResponseData

- `salarybox_id` (string, required)
- `permissions` (list of string, required) — The resulting permission set, sorted alphabetically.

## Examples

### Example

**Request**

```json
{
  "permissions": [
    "staff_details:view",
    "staff_details:edit",
    "attendance_record:view"
  ]
}
```

**Response**

```json
{
  "message": "Staff permissions updated successfully",
  "status": true,
  "data": {
    "salarybox_id": "ABCDEFGHIJ",
    "permissions": [
      "staff_details:edit",
      "staff_details:view"
    ]
  }
}
```

**SDK Code**

```python Example
import requests

url = "https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions"

payload = { "permissions": ["staff_details:view", "staff_details:edit", "attendance_record:view"] }
headers = {
    "Authorization": "Api-Key  <apiKey>",
    "Content-Type": "application/json"
}

response = requests.put(url, json=payload, headers=headers)

print(response.json())
```

```javascript Example
const url = 'https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions';
const options = {
  method: 'PUT',
  headers: {Authorization: 'Api-Key  <apiKey>', 'Content-Type': 'application/json'},
  body: '{"permissions":["staff_details:view","staff_details:edit","attendance_record:view"]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions"

	payload := strings.NewReader("{\n  \"permissions\": [\n    \"staff_details:view\",\n    \"staff_details:edit\",\n    \"attendance_record:view\"\n  ]\n}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("Authorization", "Api-Key  <apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Example
require 'uri'
require 'net/http'

url = URI("https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Api-Key  <apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"permissions\": [\n    \"staff_details:view\",\n    \"staff_details:edit\",\n    \"attendance_record:view\"\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java Example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.put("https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions")
  .header("Authorization", "Api-Key  <apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"permissions\": [\n    \"staff_details:view\",\n    \"staff_details:edit\",\n    \"attendance_record:view\"\n  ]\n}")
  .asString();
```

```php Example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions', [
  'body' => '{
  "permissions": [
    "staff_details:view",
    "staff_details:edit",
    "attendance_record:view"
  ]
}',
  'headers' => [
    'Authorization' => 'Api-Key  <apiKey>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Example
using RestSharp;

var client = new RestClient("https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Api-Key  <apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"permissions\": [\n    \"staff_details:view\",\n    \"staff_details:edit\",\n    \"attendance_record:view\"\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Example
import Foundation

let headers = [
  "Authorization": "Api-Key  <apiKey>",
  "Content-Type": "application/json"
]
let parameters = ["permissions": ["staff_details:view", "staff_details:edit", "attendance_record:view"]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Remove all permissions

**Request**

```json
{
  "permissions": []
}
```

**Response**

```json
{
  "message": "Staff permissions updated successfully",
  "status": true,
  "data": {
    "salarybox_id": "ABCDEFGHIJ",
    "permissions": [
      "staff_details:edit",
      "staff_details:view"
    ]
  }
}
```

**SDK Code**

```python Remove all permissions
import requests

url = "https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions"

payload = { "permissions": [] }
headers = {
    "Authorization": "Api-Key  <apiKey>",
    "Content-Type": "application/json"
}

response = requests.put(url, json=payload, headers=headers)

print(response.json())
```

```javascript Remove all permissions
const url = 'https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions';
const options = {
  method: 'PUT',
  headers: {Authorization: 'Api-Key  <apiKey>', 'Content-Type': 'application/json'},
  body: '{"permissions":[]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Remove all permissions
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions"

	payload := strings.NewReader("{\n  \"permissions\": []\n}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("Authorization", "Api-Key  <apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Remove all permissions
require 'uri'
require 'net/http'

url = URI("https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Api-Key  <apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"permissions\": []\n}"

response = http.request(request)
puts response.read_body
```

```java Remove all permissions
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.put("https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions")
  .header("Authorization", "Api-Key  <apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"permissions\": []\n}")
  .asString();
```

```php Remove all permissions
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions', [
  'body' => '{
  "permissions": []
}',
  'headers' => [
    'Authorization' => 'Api-Key  <apiKey>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Remove all permissions
using RestSharp;

var client = new RestClient("https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Api-Key  <apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"permissions\": []\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Remove all permissions
import Foundation

let headers = [
  "Authorization": "Api-Key  <apiKey>",
  "Content-Type": "application/json"
]
let parameters = ["permissions": []] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.salaryboxapp.com/v2/customer/v1/staff/ABCDEFGHIJ/permissions")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```