> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flowpayroll.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Permission errors

> The three refusals a request can get because of who is calling: what each means, an example body, and what to do.

Three refusals come from checking who is calling, rather than from the request's content. Each uses the shared [response format](https://docs.flowpayroll.ai/api-reference/response-format.md): branch on `message.token`, and read the details from `message.tokenArguments`. The status codes follow [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110).

| Status | `message.token` | Means | Retry? |
| - | - | - | - |
| `403` | `insufficient_permissions` | Your role does not include the permission this operation needs | No |
| `400` | `field_not_writable` | The request changes a detail nobody can change this way | No |
| `503` | `access_check_unavailable` | Access could not be checked just now | Yes, after `Retry-After` |

In none of the three is anything saved.

They are being switched on account by account as roles roll out, so handle them now rather than when you first see one.

## 403 insufficient\_permissions

The caller is known, but its role where the request applies does not include the permission the operation needs ([RFC 9110, section 15.5.4](https://www.rfc-editor.org/rfc/rfc9110#section-15.5.4)). `missingPermission` names it.

```json theme={null}
{
  "message": {
    "text": "You don't have permission to do this. Ask an administrator in your organisation for access.",
    "token": "insufficient_permissions",
    "tokenArguments": [
      { "name": "missingPermission", "value": "pay-run:lock" }
    ]
  }
}
```

**What to do.** Give the person or API token a role that includes `missingPermission` for that organisation, or have somebody who holds it make the request. Each operation names its permission in `x-flow-permission`; see [Users, roles and permissions](https://docs.flowpayroll.ai/api-reference/administration/users-roles-and-permissions.md). An API token also gets this answer when it tries to create, change or delete a role, because a token never holds a `role` permission.

## 400 field\_not\_writable

The request changes a detail that nobody can change through this operation, such as `isLeaver`, which Flow Payroll sets itself ([RFC 9110, section 15.5.1](https://www.rfc-editor.org/rfc/rfc9110#section-15.5.1)). More access never fixes it: the request itself has to change. `fields` lists the details.

```json theme={null}
{
  "message": {
    "text": "Some of these details can't be changed here.",
    "token": "field_not_writable",
    "tokenArguments": [
      { "name": "fields", "value": ["isLeaver"] }
    ]
  }
}
```

**What to do.** Remove the listed details from the request, or send them unchanged, and use the operation made for them. For example, record a leaver with `PUT /employees/{employeeId}/leaver`.

## 503 access\_check\_unavailable

Flow Payroll could not check access for this request just now ([RFC 9110, section 15.6.4](https://www.rfc-editor.org/rfc/rfc9110#section-15.6.4)). It is never a refusal: the request was not judged, and nothing was saved. The `Retry-After` header gives the number of seconds to wait ([RFC 9110, section 10.2.3](https://www.rfc-editor.org/rfc/rfc9110#section-10.2.3)).

```http theme={null}
HTTP/1.1 503 Service Unavailable
Retry-After: 1
Content-Type: application/json

{
  "message": {
    "text": "We couldn't check access to these details just now. Try again in a moment.",
    "token": "access_check_unavailable"
  }
}
```

**What to do.** Wait at least `Retry-After` seconds and send the same request again. Back off further if it repeats, and contact support if it keeps happening.

## Other access refusals

Managing access in the [Administration API](https://docs.flowpayroll.ai/api-reference/administration/overview.md) has refusals of its own, such as `role_not_yet_available`, `role_assignment_denied`, `access_management_denied`, `whole_customer_access_denied`, `duplicate_access` and `access_with_deprecated_fields`. Each operation lists the ones it can answer.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.