> ## 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.

# Provisioning users with SCIM 2.0

> Let your identity provider add, update, suspend and remove the people in your Flow Payroll account, and give them account-wide roles, over SCIM 2.0.

Flow Payroll supports SCIM 2.0 ([RFC 7643](https://www.rfc-editor.org/rfc/rfc7643) and [RFC 7644](https://www.rfc-editor.org/rfc/rfc7644)), the standard identity providers use to keep the people in other applications in step with their directory. Point your identity provider at it, and joiners, changes and leavers in your directory reach your Flow Payroll account without anybody inviting or removing them by hand.

SCIM sits next to the people operations of the [Administration API](https://docs.flowpayroll.ai/api-reference/administration/overview.md), which keep working. Use either; both change the same people.

## Base URL

```text theme={null}
https://api.flowpayroll.ai/v1/administration/scim/v2
```

In sandbox, use `https://api.sandbox.flowpayroll.ai/v1/administration/scim/v2`.

## Authentication

SCIM is called by one of your account's API tokens, never by a person.

1. Create an API token for your identity provider with `POST /api-tokens`, sending `allOrganisations: true` for **account-wide access**, and a role that includes `user:write`, such as Administrator (HR integration, once it can be given). To suspend and remove people as well, the role also needs `user:delete`.
2. Exchange its client id and secret for an access token, as for any API token. See [Authentication](https://docs.flowpayroll.ai/api-reference/authentication.md).
3. Send the access token as `Authorization: Bearer <token>`. SCIM clients send their credential this way, so SCIM takes it there rather than in `X-Auth-Token`.

A person's credentials, or a token without `user:write` across the whole account, get `403`. The discovery endpoints below can be read by any caller of your account.

## What is supported

| Endpoint | Supported |
| - | - |
| `/ServiceProviderConfig`, `/ResourceTypes`, `/Schemas` | Read |
| `/Users` | List, filter, create, read, replace (`PUT`), change (`PATCH`), delete |
| `/Groups` | List, filter, read, replace members (`PUT`), add or remove members (`PATCH`) |
| `/Groups` create and delete, `/Bulk`, `/Me` | Not supported: `501` |

`/ServiceProviderConfig` says the same thing to your identity provider: `PATCH` and filtering are supported, bulk, sorting, password changes and ETags are not.

Every answer, errors included, is `application/scim+json` in the shapes RFC 7644 defines, with a `scimType` where one applies.

## Users

A SCIM user is a person who can sign in to your account.

| Attribute | Notes |
| - | - |
| `userName` | The person's sign-in email address. Required, unique, and never changes (`400` with `mutability`). To change it, delete the user and provision them again with the new address. |
| `name.givenName`, `name.familyName` | First name (required) and last name. |
| `displayName` | Can change. |
| `externalId` | Your directory's id for the person. Unique in your account. |
| `emails` | Read-only, from `userName`. |
| `active` | `false` suspends the person, `true` restores them. |

* **Create** (`POST /Users`) adds the person across your whole account with your account's [default role](https://docs.flowpayroll.ai/api-reference/administration/users-roles-and-permissions.md#the-default-role). While only Administrator can be given, that is Administrator. A `userName` or `externalId` already in your account answers `409` with `uniqueness`.
* **Suspend** with `active: false`: their sign-in is disabled, they are signed out everywhere, and their access is kept for when they return. `active: true` lets them sign in again. Both need `user:delete`.
* **Delete** (`DELETE /Users/{id}`) removes the person from your account: their access goes, and their sign-in is disabled and signed out everywhere. It answers `204` and needs `user:delete`.
* The account owner can never be suspended or removed over SCIM (`403`). Once roles other than Administrator can be given, a person who holds more than your API token does cannot be suspended or removed by it either (`403`).
* `PATCH` follows RFC 7644 and is all or nothing: if one operation fails, none is applied.
* `GET /Users/{id}` answers `404` for anybody who is not one of your account's people.

## Groups are roles

Each SCIM group is a role a person can hold, and its `id` is the role's `roleId`, such as `payroll-manager` or `custom.hr-team`. Roles themselves are created, changed and deleted in the admin area or with `/roles`, never over SCIM, and a group's `displayName` cannot change.

* Adding a person to a group gives them that role across your whole account, including organisations added later.
* Removing them gives them your account's default role back.
* `PUT /Groups/{id}` replaces everybody who holds the role across your account with the `members` you send.
* The same rules as everywhere else decide which roles can be given. See [Users, roles and permissions](https://docs.flowpayroll.ai/api-reference/administration/users-roles-and-permissions.md).

Every group carries `urn:flowpayroll:scim:schemas:extension:access:2.0:Group` with `scope` set to `Account`: membership always means the whole account. Give access to some organisations only, or through an organisation group, in the admin area or with `/users`.

## Filtering and paging

| | |
| - | - |
| Filters on `/Users` | `userName eq`, `externalId eq` and `id eq` only. Anything else answers `400` with `invalidFilter`. |
| Filters on `/Groups` | `displayName eq` and `id eq`. `excludedAttributes=members` leaves members out. |
| Default paging | By cursor ([RFC 9865](https://www.rfc-editor.org/rfc/rfc9865)): send `count`, and follow `nextCursor` until it is absent. |
| Index paging | Send `startIndex` (from 1) instead, as RFC 7644 describes. Sending both `startIndex` and `cursor` answers `400` with `invalidValue`. |
| Page size | `count` is 50 by default and at most 100. A larger `count` returns 100. |

## Other answers

* `412` when somebody else changed the same person or role first. Read it again and repeat the change.
* `503` when access could not be checked just now. Nothing was changed; try again in a moment.

## Limits

* No bulk requests: send each change on its own.
* No sorting, no password changes and no ETags.
* At most 100 results per page, and per filter.
* One role per person across the whole account through SCIM.


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