> This page is for API, version 2026-01-01 (Stable) (default).
> For other versions, use one of these documentation indexes:
> - 2026-01-01 (Stable) (default): https://docs.deel.wtf/api/stable/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.deel.wtf/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.deel.wtf/_mcp/server.

# List users

GET https://api.letsdeel.com/scim/v2/Users

Lists users in the Deel HRIS using the SCIM user format. Use it to read the list of users through the SCIM interface or to search users by email address.

 **Token scopes**: `Users:read`

Reference: https://docs.deel.wtf/api/reference/endpoints/users/get-users

## Authentication

- `Authorization` header (bearer token, required) — ## Authentication The Deel API uses bearer tokens to authenticate requests. All API calls must be made over HTTPS — calls over plain HTTP or without authentication will fail. ```curl curl -X GET 'https://api.deel.training/rest/v2/contracts' \ -H 'Authorization: Bearer YOUR-TOKEN-HERE' ``` [Learn more about authentication](/api/authentication)
- `Authorization` header (bearer token, required) — Standard OAuth2 security scheme based on https://swagger.io/docs/specification/authentication/

## Servers

- `https://api.letsdeel.com/scim/v2` (Production, default)
- `https://api-staging.letsdeel.com/scim/v2` (Demo)

## Request

### Query parameters

- `filter` (UsersGetParametersFilter, optional) — Filter results using [SCIM's filtering syntax](https://datatracker.ietf.org/doc/html/rfc7644#section-3.4.2.2). Currently supports only `eq` operator and filtering by a user's email. Expected format 'email eq "email@domain.com"'.
- `startIndex` (string, optional) — The 1-based index of the first result to return. Used for pagination. Minimum value is 1. Defaults to 1 if not provided.
- `count` (string, optional) — The maximum number of results to return per page. Used for pagination. A value of 0 is treated as a special case and returns 1 result. Typically should be a positive integer.

## Response

### 200

Successful response

- `schemas` (list of enum, optional)
  - Allowed values: `urn:ietf:params:scim:api:messages:2.0:ListResponse`
- `Resources` (list of UsersGetResponsesContentApplicationJsonSchemaResourcesItems, optional)
- `startIndex` (long, optional)
- `itemsPerPage` (long, optional)
- `totalResults` (long, optional)

## Errors

### 400 Bad Request Error

Operation failed.

- `detail` (string, optional) — detail error message
- `schemas` (list of enum, optional)
  - Allowed values: `urn:ietf:params:scim:api:messages:2.0:Error`
- `scimType` (enum, optional) — bad request type when status code is 400
  - Allowed values: `uniqueness`, `tooMany`, `mutability`, `sensitive`, `invalidSyntax`, `invalidFilter`, `invalidPath`, `invalidValue`, `invalidVers`, `noTarget`
- `status` (string, optional) — same as HTTP status code, e.g. 400, 401, etc.

### 401 Unauthorized Error

Operation failed.

- `detail` (string, optional) — detail error message
- `schemas` (list of enum, optional)
  - Allowed values: `urn:ietf:params:scim:api:messages:2.0:Error`
- `scimType` (enum, optional) — bad request type when status code is 400
  - Allowed values: `uniqueness`, `tooMany`, `mutability`, `sensitive`, `invalidSyntax`, `invalidFilter`, `invalidPath`, `invalidValue`, `invalidVers`, `noTarget`
- `status` (string, optional) — same as HTTP status code, e.g. 400, 401, etc.

### 403 Forbidden Error

Operation failed.

- `detail` (string, optional) — detail error message
- `schemas` (list of enum, optional)
  - Allowed values: `urn:ietf:params:scim:api:messages:2.0:Error`
- `scimType` (enum, optional) — bad request type when status code is 400
  - Allowed values: `uniqueness`, `tooMany`, `mutability`, `sensitive`, `invalidSyntax`, `invalidFilter`, `invalidPath`, `invalidValue`, `invalidVers`, `noTarget`
- `status` (string, optional) — same as HTTP status code, e.g. 400, 401, etc.

### 404 Not Found Error

Operation failed.

- `detail` (string, optional) — detail error message
- `schemas` (list of enum, optional)
  - Allowed values: `urn:ietf:params:scim:api:messages:2.0:Error`
- `scimType` (enum, optional) — bad request type when status code is 400
  - Allowed values: `uniqueness`, `tooMany`, `mutability`, `sensitive`, `invalidSyntax`, `invalidFilter`, `invalidPath`, `invalidValue`, `invalidVers`, `noTarget`
- `status` (string, optional) — same as HTTP status code, e.g. 400, 401, etc.

### 500 Internal Server Error

Internal Server Error

- `error` (UsersGetResponsesContentApplicationJsonSchemaError, required)

## Types

### UsersGetParametersFilter

- string
- list of string

### UsersGetResponsesContentApplicationJsonSchemaResourcesItems

- `meta` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsMeta, required)
- `name` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsName, required)
- `emails` (list of UsersGetResponsesContentApplicationJsonSchemaResourcesItemsEmailsItems, required)
- `schemas` (list of enum, required)
  - Allowed values: `urn:ietf:params:scim:schemas:core:2.0:User`
- `userName` (string, required)
- `id` (string, optional)
- `title` (string, optional)
- `active` (boolean, optional, default: false)
- `userType` (string, optional)
- `addresses` (list of UsersGetResponsesContentApplicationJsonSchemaResourcesItemsAddressesItems, optional)
- `urn:ietf:params:scim:schemas:extension:2.0:User` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20User, optional)
- `urn:ietf:params:scim:schemas:extension:enterprise:2.0:User` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtensionEnterprise20User, optional)

### UsersGetResponsesContentApplicationJsonSchemaError

- `code` (string, required) — Error code identifying the type of error.
- `message` (string, required) — Error message describing what went wrong.
- `details` (string, optional, nullable) — Additional details about the error.

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsMeta

- `created` (string, optional)
- `location` (string, optional)
- `lastModified` (string, optional)
- `resourceType` (enum, optional)
  - Allowed values: `User`, `Group`

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsName

- `givenName` (string, required, nullable)
- `familyName` (string, required, nullable)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsEmailsItems

- `type` (enum, required)
  - Allowed values: `home`, `work`, `other`
- `value` (string, required)
- `primary` (boolean, optional, default: false)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsAddressesItems

- `type` (string, optional)
- `region` (string, optional)
- `country` (string, optional, nullable)
- `lineTwo` (string, optional)
- `locality` (string, optional)
- `postalCode` (string, optional)
- `streetAddress` (string, optional)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20User

- `state` (string, optional, nullable)
- `country` (string, optional, nullable)
- `endDate` (string, optional)
- `birthday` (string, optional)
- `workerId` (string, optional, nullable)
- `isManager` (boolean, optional, default: false)
- `startDate` (string, optional, nullable)
- `jobProfile` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserJobProfile, optional, nullable) — Active job profile of the worker from job architecture. Present only when job profiles are enabled for the organization and job architecture is set up; null when the worker has no active job profile or the token lacks the job_profile.view permission.
- `employments` (list of UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserEmploymentsItems, optional, nullable)
- `customFields` (list of UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserCustomFieldsItems, optional, nullable)
- `hiringStatus` (string, optional)
- `workLocation` (string, optional, nullable) — The work location label assigned to the worker's HRIS profile
- `preferredName` (string, optional)
- `preferredLastName` (string, optional)
- `preferredFirstName` (string, optional)
- `departmentHierarchy` (string, optional, nullable)
- `departmentExternalId` (string, optional, nullable)
- `departmentCustomFields` (map from string to string, optional, nullable) — Org-structure custom fields resolved for the department node, keyed by normalized field name. Only present when the department custom fields feature flag is enabled for the organization.
- `organizationalStructures` (list of UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserOrganizationalStructuresItems, optional)
- `departmentExternalIdHierarchy` (string, optional, nullable)
- `workerTerminationLastDateOfWork` (string, optional, nullable)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtensionEnterprise20User

- `manager` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtensionEnterprise20UserManager, optional)
- `costCenter` (string, optional)
- `department` (string, optional)
- `customFields` (map from string to string, optional)
- `organization` (string, optional)
- `preferredLastName` (string, optional)
- `preferredFirstName` (string, optional)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserJobProfile

Active job profile of the worker from job architecture. Present only when job profiles are enabled for the organization and job architecture is set up; null when the worker has no active job profile or the token lacks the job_profile.view permission.

- `id` (string, optional) — Job profile id.
- `name` (string, optional) — Job profile name.
- `level` (integer, optional, nullable) — Job profile level.
- `track` (string, optional, nullable) — Job profile track, as configured in job architecture (free text).
- `jobFamily` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserJobProfileJobFamily, optional, nullable) — Job family of the job profile.
- `jobFamilyGroup` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserJobProfileJobFamilyGroup, optional, nullable) — Job family group of the job family.

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserEmploymentsItems

- `team` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserEmploymentsItemsTeam, optional)
- `state` (string, optional, nullable)
- `title` (string, optional, nullable)
- `active` (boolean, optional, default: false)
- `country` (string, optional, nullable)
- `startDate` (string, optional, nullable)
- `contractId` (string, optional)
- `contractType` (string, optional, nullable)
- `customFields` (list of UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserEmploymentsItemsCustomFieldsItems, optional) — Contract-level custom fields associated with the employment
- `employeeNumber` (string, optional, nullable)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserCustomFieldsItems

- `id` (string, optional)
- `name` (string, optional, nullable)
- `value` (string, optional, nullable)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserOrganizationalStructuresItems

- `name` (string, optional)
- `externalId` (string, optional, nullable)
- `structureId` (string, optional)
- `nameHierarchy` (string, optional)
- `structureName` (string, optional)
- `externalIdHierarchy` (string, optional, nullable)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtensionEnterprise20UserManager

- `value` (string, required)
- `email` (string, optional)
- `displayName` (string, optional)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserJobProfileJobFamily

Job family of the job profile.

- `id` (string, optional) — Job family id.
- `name` (string, optional) — Job family name.

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserJobProfileJobFamilyGroup

Job family group of the job family.

- `id` (string, optional) — Job family group id.
- `name` (string, optional) — Job family group name.

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserEmploymentsItemsTeam

- `name` (string, optional, nullable)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserEmploymentsItemsCustomFieldsItems

- `id` (string, optional)
- `data` (UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserEmploymentsItemsCustomFieldsItemsData, optional, nullable) — The custom field value payload. Structure varies by field type: Text/Number/Date have \{value}, Percentage has \{value, text}, Currency has \{amount, currency}, List has \{option}, Multiselect has \{options}.
- `name` (string, optional)
- `type` (string, optional)

### UsersGetResponsesContentApplicationJsonSchemaResourcesItemsUrnIetfParamsScimSchemasExtension20UserEmploymentsItemsCustomFieldsItemsData

The custom field value payload. Structure varies by field type: Text/Number/Date have \{value}, Percentage has \{value, text}, Currency has \{amount, currency}, List has \{option}, Multiselect has \{options}.

## Examples

**Response**

```json
{
  "schemas": [
    "urn:ietf:params:scim:api:messages:2.0:ListResponse"
  ],
  "Resources": [
    {
      "meta": {
        "created": "string",
        "location": "string",
        "lastModified": "string",
        "resourceType": "User"
      },
      "name": {
        "givenName": "string",
        "familyName": "string"
      },
      "emails": [
        {
          "type": "home",
          "value": "string",
          "primary": false
        }
      ],
      "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
      ],
      "userName": "string",
      "id": "string",
      "title": "string",
      "active": false,
      "userType": "string",
      "addresses": [
        {
          "type": "string",
          "region": "string",
          "country": "string",
          "lineTwo": "string",
          "locality": "string",
          "postalCode": "string",
          "streetAddress": "string"
        }
      ],
      "urn:ietf:params:scim:schemas:extension:2.0:User": {
        "state": "string",
        "country": "string",
        "endDate": "string",
        "birthday": "string",
        "workerId": "string",
        "isManager": false,
        "startDate": "string",
        "jobProfile": {
          "id": "1f94c23b-6c1e-4f8a-9a39-2d1f0e5b7c11",
          "name": "Account Management - PM2",
          "level": 2,
          "track": "MANAGEMENT",
          "jobFamily": {
            "id": "5a7d2e10-3c4b-4f61-8e9a-0b1c2d3e4f50",
            "name": "Account Management"
          },
          "jobFamilyGroup": {
            "id": "9c8b7a65-4d3e-4f21-9a0b-1c2d3e4f5a6b",
            "name": "Sales"
          }
        },
        "employments": [
          {
            "team": {
              "name": "string"
            },
            "state": "string",
            "title": "string",
            "active": false,
            "country": "string",
            "startDate": "string",
            "contractId": "string",
            "contractType": "string",
            "customFields": [
              {
                "id": "string",
                "data": {},
                "name": "string",
                "type": "string"
              }
            ],
            "employeeNumber": "string"
          }
        ],
        "customFields": [
          {
            "id": "string",
            "name": "string",
            "value": "string"
          }
        ],
        "hiringStatus": "string",
        "workLocation": "string",
        "preferredName": "string",
        "preferredLastName": "string",
        "preferredFirstName": "string",
        "departmentHierarchy": "string",
        "departmentExternalId": "string",
        "departmentCustomFields": {
          "finance_department": "R&D"
        },
        "organizationalStructures": [
          {
            "name": "string",
            "externalId": "string",
            "structureId": "string",
            "nameHierarchy": "string",
            "structureName": "string",
            "externalIdHierarchy": "string"
          }
        ],
        "departmentExternalIdHierarchy": "string",
        "workerTerminationLastDateOfWork": "string"
      },
      "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
        "manager": {
          "value": "string",
          "email": "string",
          "displayName": "string"
        },
        "costCenter": "string",
        "department": "string",
        "customFields": {},
        "organization": "string",
        "preferredLastName": "string",
        "preferredFirstName": "string"
      }
    }
  ],
  "startIndex": 1,
  "itemsPerPage": 1,
  "totalResults": 1
}
```

**SDK Code**

```python
import requests

url = "https://api.letsdeel.com/scim/v2/Users"

querystring = {"count":"50","filter":"email eq \"user@example.com\"","startIndex":"1"}

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers, params=querystring)

print(response.json())
```

```javascript
const url = 'https://api.letsdeel.com/scim/v2/Users?count=50&filter=email+eq+%22user%40example.com%22&startIndex=1';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

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

```go
package main

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

func main() {

	url := "https://api.letsdeel.com/scim/v2/Users?count=50&filter=email+eq+%22user%40example.com%22&startIndex=1"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

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

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

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

}
```

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

url = URI("https://api.letsdeel.com/scim/v2/Users?count=50&filter=email+eq+%22user%40example.com%22&startIndex=1")

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

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

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

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

HttpResponse<String> response = Unirest.get("https://api.letsdeel.com/scim/v2/Users?count=50&filter=email+eq+%22user%40example.com%22&startIndex=1")
  .header("Authorization", "Bearer <token>")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.letsdeel.com/scim/v2/Users?count=50&filter=email+eq+%22user%40example.com%22&startIndex=1', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://api.letsdeel.com/scim/v2/Users?count=50&filter=email+eq+%22user%40example.com%22&startIndex=1");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.letsdeel.com/scim/v2/Users?count=50&filter=email+eq+%22user%40example.com%22&startIndex=1")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

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()
```