openapi: 3.1.0
info:
title: Deel HRIS API
description: |
Unified HR Information System API across all worker types (IC, EOR, employee).
Surfaces include people directory, working locations, time off (policies, requests,
entitlements, events, work schedules), positions, employment information, departments,
manager hierarchy, custom HR fields, and SCIM 2.0 user provisioning for Okta, Azure AD,
and other identity providers.
version: '2026-05-25'
contact:
name: Deel Developer Support
url: https://developer.deel.com/api/hris/introduction
servers:
- url: https://api.letsdeel.com/rest/v2
description: Production
- url: https://api-sandbox.demo.deel.com/rest/v2
description: Sandbox
security:
- BearerAuth: []
- ScimBearerAuth: []
tags:
- name: People
description: Unified directory across IC, EOR, and direct employees
- name: Time Off
description: Time-off policies, requests, entitlements, events, work schedules
- name: Positions
description: Position/role definitions
- name: SCIM
description: SCIM 2.0 user provisioning per RFC 7643/7644
paths:
/people:
get:
operationId: getPeople
summary: List Of People
description: Returns a paginated unified directory across all worker types.
tags: [People]
parameters:
- { name: after_cursor, in: query, schema: { type: string } }
- { name: limit, in: query, schema: { type: integer, default: 20, maximum: 100 } }
- { name: hiring_type, in: query, schema: { type: string, enum: [contractor, eor, direct_employee, global_payroll] } }
- { name: employment_status, in: query, schema: { type: string, enum: [active, terminated, onboarding, offboarded] } }
- { name: country, in: query, schema: { type: string } }
responses:
'200':
description: People list
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/Person' } }
post:
operationId: createPersonWithoutContract
summary: Create A Person Without A Contract
description: Create a person record (for example a future hire) before any contract exists.
tags: [People]
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/PersonCreate' }
responses:
'201':
description: Person created
content:
application/json:
schema: { $ref: '#/components/schemas/Person' }
/people/{person_id}:
get:
operationId: getPersonById
summary: Retrieve A Single Person
tags: [People]
parameters:
- { name: person_id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: Person
content:
application/json:
schema: { $ref: '#/components/schemas/Person' }
/people/{person_id}/working-location:
patch:
operationId: updateWorkingLocation
summary: Update Working Location
tags: [People]
parameters:
- { name: person_id, in: path, required: true, schema: { type: string } }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/WorkingLocationUpdate' }
responses:
'200': { description: Location updated }
/time-off/policies:
get:
operationId: getTimeOffPolicies
summary: List Policies
tags: [Time Off]
responses:
'200':
description: Policies
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/TimeOffPolicy' } }
/time-off/requests:
get:
operationId: getTimeOffRequests
summary: List Time-Off Requests
tags: [Time Off]
parameters:
- { name: person_id, in: query, schema: { type: string } }
- { name: status, in: query, schema: { type: string, enum: [pending, approved, declined, cancelled] } }
- { name: from, in: query, schema: { type: string, format: date } }
- { name: to, in: query, schema: { type: string, format: date } }
responses:
'200':
description: Time-off requests
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/TimeOffRequest' } }
post:
operationId: createTimeOffRequest
summary: Create Time-Off Request
tags: [Time Off]
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/TimeOffRequestCreate' }
responses:
'201':
description: Time-off request created
content:
application/json:
schema: { $ref: '#/components/schemas/TimeOffRequest' }
/time-off/requests/{request_id}/review:
post:
operationId: reviewTimeOffRequest
summary: Approve Or Reject Time-Off Requests
tags: [Time Off]
parameters:
- { name: request_id, in: path, required: true, schema: { type: string } }
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [decision]
properties:
decision: { type: string, enum: [approve, decline] }
notes: { type: string }
responses:
'200': { description: Request reviewed }
/time-off/requests/{request_id}:
delete:
operationId: cancelTimeOffRequest
summary: Cancel Time-Off Request
tags: [Time Off]
parameters:
- { name: request_id, in: path, required: true, schema: { type: string } }
responses:
'204': { description: Request cancelled }
/time-off/entitlements/{person_id}:
get:
operationId: getEntitlements
summary: Get Profile Entitlements
tags: [Time Off]
parameters:
- { name: person_id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: Entitlements
content:
application/json:
schema:
type: object
properties:
data: { type: array, items: { $ref: '#/components/schemas/Entitlement' } }
/time-off/work-schedule/{person_id}:
get:
operationId: getWorkSchedule
summary: Get Work Schedule And Holidays
tags: [Time Off]
parameters:
- { name: person_id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: Work schedule
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
working_days: { type: array, items: { type: string } }
hours_per_week: { type: number }
holidays: { type: array, items: { type: object, properties: { date: { type: string, format: date }, name: { type: string } } } }
/scim/v2/Users:
get:
operationId: scimListUsers
summary: SCIM List Users
description: SCIM 2.0 user listing endpoint for IdP integration (Okta, Azure AD).
tags: [SCIM]
security:
- ScimBearerAuth: []
parameters:
- { name: filter, in: query, schema: { type: string } }
- { name: startIndex, in: query, schema: { type: integer, default: 1 } }
- { name: count, in: query, schema: { type: integer, default: 100 } }
responses:
'200':
description: SCIM ListResponse
content:
application/scim+json:
schema: { $ref: '#/components/schemas/ScimListResponse' }
post:
operationId: scimCreateUser
summary: SCIM Create User
tags: [SCIM]
security:
- ScimBearerAuth: []
requestBody:
required: true
content:
application/scim+json:
schema: { $ref: '#/components/schemas/ScimUser' }
responses:
'201':
description: SCIM user created
content:
application/scim+json:
schema: { $ref: '#/components/schemas/ScimUser' }
/scim/v2/Users/{user_id}:
get:
operationId: scimGetUser
summary: SCIM Get User
tags: [SCIM]
security:
- ScimBearerAuth: []
parameters:
- { name: user_id, in: path, required: true, schema: { type: string } }
responses:
'200':
description: SCIM user
content:
application/scim+json:
schema: { $ref: '#/components/schemas/ScimUser' }
patch:
operationId: scimPatchUser
summary: SCIM Patch User
tags: [SCIM]
security:
- ScimBearerAuth: []
parameters:
- { name: user_id, in: path, required: true, schema: { type: string } }
requestBody:
required: true
content:
application/scim+json:
schema:
type: object
properties:
schemas: { type: array, items: { type: string } }
Operations:
type: array
items:
type: object
properties:
op: { type: string, enum: [add, replace, remove] }
path: { type: string }
value: {}
responses:
'200': { description: Patched, content: { application/scim+json: { schema: { $ref: '#/components/schemas/ScimUser' } } } }
delete:
operationId: scimDeleteUser
summary: SCIM Deactivate User
tags: [SCIM]
security:
- ScimBearerAuth: []
parameters:
- { name: user_id, in: path, required: true, schema: { type: string } }
responses:
'204': { description: User deactivated }
components:
securitySchemes:
BearerAuth: { type: http, scheme: bearer, bearerFormat: opaque }
ScimBearerAuth:
type: http
scheme: bearer
bearerFormat: scim_token
description: Dedicated SCIM bearer token configured per IdP in the Developer Center.
parameters:
IdempotencyKey:
name: Idempotency-Key
in: header
required: false
schema: { type: string, format: uuid }
schemas:
Person:
type: object
properties:
id: { type: string }
first_name: { type: string }
last_name: { type: string }
preferred_name: { type: string }
email: { type: string, format: email }
work_email: { type: string, format: email }
hiring_type: { type: string, enum: [contractor, eor, direct_employee, global_payroll] }
employment_status: { type: string, enum: [active, terminated, onboarding, offboarded] }
country: { type: string }
working_location: { $ref: '#/components/schemas/WorkingLocation' }
department: { type: object, properties: { id: { type: string }, name: { type: string } } }
manager: { type: object, properties: { id: { type: string }, name: { type: string } } }
job_title: { type: string }
start_date: { type: string, format: date }
external_id: { type: string }
PersonCreate:
type: object
required: [first_name, last_name, email]
properties:
first_name: { type: string }
last_name: { type: string }
email: { type: string, format: email }
preferred_name: { type: string }
country: { type: string }
job_title: { type: string }
external_id: { type: string }
WorkingLocation:
type: object
properties:
country: { type: string }
state: { type: string }
city: { type: string }
address: { type: string }
timezone: { type: string }
WorkingLocationUpdate:
type: object
required: [country]
properties:
country: { type: string }
state: { type: string }
city: { type: string }
address: { type: string }
timezone: { type: string }
effective_date: { type: string, format: date }
TimeOffPolicy:
type: object
properties:
id: { type: string }
name: { type: string }
type: { type: string, enum: [vacation, sick, parental, bereavement, jury_duty, study, unpaid, other] }
accrual_rate: { type: number }
accrual_unit: { type: string, enum: [days, hours] }
carry_over_days: { type: integer }
country: { type: string }
TimeOffRequest:
type: object
properties:
id: { type: string }
person_id: { type: string }
policy_id: { type: string }
type: { type: string }
start_date: { type: string, format: date }
end_date: { type: string, format: date }
days: { type: number }
status: { type: string, enum: [pending, approved, declined, cancelled] }
reason: { type: string }
created_at: { type: string, format: date-time }
TimeOffRequestCreate:
type: object
required: [person_id, policy_id, start_date, end_date]
properties:
person_id: { type: string }
policy_id: { type: string }
start_date: { type: string, format: date }
end_date: { type: string, format: date }
reason: { type: string }
half_day: { type: boolean }
Entitlement:
type: object
properties:
policy_id: { type: string }
policy_name: { type: string }
accrued: { type: number }
used: { type: number }
pending: { type: number }
available: { type: number }
unit: { type: string, enum: [days, hours] }
as_of: { type: string, format: date }
ScimListResponse:
type: object
properties:
schemas: { type: array, items: { type: string }, example: ["urn:ietf:params:scim:api:messages:2.0:ListResponse"] }
totalResults: { type: integer }
startIndex: { type: integer }
itemsPerPage: { type: integer }
Resources: { type: array, items: { $ref: '#/components/schemas/ScimUser' } }
ScimUser:
type: object
properties:
schemas: { type: array, items: { type: string }, example: ["urn:ietf:params:scim:schemas:core:2.0:User"] }
id: { type: string }
userName: { type: string }
active: { type: boolean }
name:
type: object
properties:
givenName: { type: string }
familyName: { type: string }
emails:
type: array
items:
type: object
properties:
value: { type: string, format: email }
type: { type: string }
primary: { type: boolean }
externalId: { type: string }
meta:
type: object
properties:
resourceType: { type: string }
created: { type: string, format: date-time }
lastModified: { type: string, format: date-time }
location: { type: string, format: uri }