Summary and recommendation
HiBob exposes a REST API at https://api.hibob.com/v1 using HTTP Basic Auth with Base64-encoded Service User credentials (serviceUserId:serviceUserToken). Service User permissions are granular and must be explicitly granted per data category - People, Payroll, Documents - in HiBob admin before any API call to those resources will succeed.
The API uses cursor-based pagination (pageSize up to 1000, next cursor token in response); offset-based pagination is not supported. Rate limits are enforced per Service User but exact thresholds are not publicly documented; implement exponential backoff on 429 responses and respect the Retry-After header.
HiBob's internal numeric/string employee IDs are the primary key across all endpoints - email addresses are not accepted as path parameters, so ID resolution via list or search endpoints is a required first step for any targeted operation.
API quick reference
| Has user API | Yes |
| Auth method | HTTP Basic Auth using Service User credentials (serviceUserId:serviceUserToken encoded as Base64), or Bearer token for some integrations |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | All plans (SSO prerequisite required) |
Authentication
Auth method: HTTP Basic Auth using Service User credentials (serviceUserId:serviceUserToken encoded as Base64), or Bearer token for some integrations
Setup steps
- Navigate to HiBob Settings > Integrations > Service Users
- Create a new Service User and assign appropriate permissions (read/write on People, etc.)
- Copy the generated Service User ID and Token
- Encode 'serviceUserId:serviceUserToken' in Base64
- Set Authorization header: 'Authorization: Basic
' - Alternatively, use the raw token as 'Authorization: Bearer
' if using token-based auth per integration docs
Required scopes
| Scope | Description | Required for |
|---|---|---|
| People - Read | Read access to employee profiles and people data | GET /people, GET /people/{id} |
| People - Write | Create and update employee records | POST /people, PUT /people/{id}, PATCH /people/{id}/work |
| People - Delete | Terminate or delete employee records | DELETE /people/{id}, POST /people/{id}/employment/terminate |
| Documents - Read | Read employee documents | GET /docs/people/{id} |
| Payroll - Read | Read payroll and compensation data | GET /payroll/history |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | HiBob internal employee ID | auto-generated | immutable | Used as path parameter in all employee-specific endpoints |
| firstName | string | Employee first name | required | optional | Part of work.name object in some contexts |
| surname | string | Employee last name | required | optional | Also referred to as 'lastName' in SCIM context |
| string | Work email address | required | optional | Must be unique; used as login identifier | |
| work.startDate | string (date) | Employee start date in ISO 8601 format (YYYY-MM-DD) | required | optional | Determines when employee becomes active in the system |
| work.site | string | Office site/location name | optional | optional | Must match an existing site configured in HiBob settings |
| work.department | string | Department name | optional | optional | Must match existing department in HiBob |
| work.title | string | Job title | optional | optional | |
| work.reportsTo.id | string | HiBob ID of the direct manager | optional | optional | Manager must already exist in HiBob |
| work.employmentType | string | Employment type (e.g., 'Employee', 'Contractor') | optional | optional | Must match list values configured in HiBob |
| personal.pronouns | string | Employee preferred pronouns | optional | optional | |
| personal.birthday | string (date) | Date of birth | optional | optional | Format: YYYY-MM-DD |
| about.hobbies | array | Employee hobbies (profile enrichment) | optional | optional | Custom/optional profile field |
| work.customColumns | object | Custom fields defined in HiBob admin | optional | optional | Field names vary per HiBob instance configuration |
| payroll.employment.salaryPayType | string | Pay type (e.g., 'Salary', 'Hourly') | optional | optional | Requires Payroll write scope |
Core endpoints
List all employees
- Method: GET
- URL:
https://api.hibob.com/v1/people - Watch out for: Inactive employees excluded by default; use showInactive=true to include terminated staff. Paginate using the 'next' cursor from the response.
Request example
GET /v1/people?showInactive=false&pageSize=100
Authorization: Basic <base64>
Response example
{
"employees": [
{"id":"1234","firstName":"Jane","surname":"Doe","email":"jane@co.com"}
],
"next": "cursor_token_abc"
}
Get single employee
- Method: GET
- URL:
https://api.hibob.com/v1/people/{id} - Watch out for: The {id} is HiBob's internal ID, not email. Resolve email-to-ID via the list endpoint first.
Request example
GET /v1/people/1234
Authorization: Basic <base64>
Response example
{
"id": "1234",
"firstName": "Jane",
"surname": "Doe",
"email": "jane@co.com",
"work": {"title": "Engineer", "department": "R&D"}
}
Create employee
- Method: POST
- URL:
https://api.hibob.com/v1/people - Watch out for: Only the new employee's ID is returned on creation. A separate GET is needed to retrieve the full profile. startDate is required.
Request example
POST /v1/people
Content-Type: application/json
{
"firstName":"John","surname":"Smith",
"email":"john@co.com",
"work":{"startDate":"2024-06-01"}
}
Response example
{
"id": "5678"
}
Update work details
- Method: PUT
- URL:
https://api.hibob.com/v1/people/{id}/work - Watch out for: Work history entries are appended, not overwritten. Each PUT creates a new work history record with an effective date.
Request example
PUT /v1/people/1234/work
Content-Type: application/json
{
"title": "Senior Engineer",
"department": "Platform"
}
Response example
HTTP 200 OK
{}
Search employees (bulk filter)
- Method: POST
- URL:
https://api.hibob.com/v1/people/search - Watch out for: Preferred over repeated GET calls for bulk operations. Field paths must match HiBob's internal schema names exactly.
Request example
POST /v1/people/search
{
"filters": [{"fieldPath":"work.department","operator":"equals","values":["Engineering"]}],
"fields": ["firstName","surname","email"]
}
Response example
{
"employees": [
{"id":"1234","firstName":"Jane","email":"jane@co.com"}
]
}
Terminate employee
- Method: POST
- URL:
https://api.hibob.com/v1/people/{id}/employment/terminate - Watch out for: Termination is not reversible via API. terminationReason must match a value configured in HiBob's termination reasons list.
Request example
POST /v1/people/1234/employment/terminate
{
"terminationDate": "2024-12-31",
"terminationReason": "Resignation"
}
Response example
HTTP 200 OK
{}
Read employee documents
- Method: GET
- URL:
https://api.hibob.com/v1/docs/people/{id} - Watch out for: Document download URLs are pre-signed and time-limited. Cache the metadata, not the URL.
Request example
GET /v1/docs/people/1234
Authorization: Basic <base64>
Response example
{
"documents": [
{"id":"doc_1","name":"Offer Letter","url":"https://..."}
]
}
Get payroll history
- Method: GET
- URL:
https://api.hibob.com/v1/payroll/history - Watch out for: Requires explicit Payroll read permission on the Service User. Returns all employees' payroll changes in the date range, not per-employee.
Request example
GET /v1/payroll/history?fromDate=2024-01-01&toDate=2024-12-31
Authorization: Basic <base64>
Response example
{
"payrollHistory": [
{"employeeId":"1234","salary":90000,"currency":"USD","effectiveDate":"2024-01-01"}
]
}
Rate limits, pagination, and events
- Rate limits: HiBob enforces rate limits per service user. Official documentation does not publicly specify exact request-per-minute limits; limits are enforced and a 429 response is returned when exceeded.
- Rate-limit headers: Yes
- Retry-After header: Yes
- Rate-limit notes: On 429, respect the Retry-After header. HiBob recommends implementing exponential backoff. Bulk endpoints (e.g., POST /people/search) are preferred over repeated single-record calls to reduce rate limit pressure.
- Pagination method: cursor
- Default page size: 100
- Max page size: 1000
- Pagination pointer: pageSize / cursor (returned in response as 'next' cursor token)
| Plan | Limit | Concurrent |
|---|---|---|
| All plans | Not publicly documented; 429 returned on breach | 0 |
- Webhooks available: Yes
- Webhook notes: HiBob supports webhooks to push real-time event notifications to a configured endpoint URL. Webhooks are configured in Settings > Integrations > Webhooks.
- Alternative event strategy: If webhooks are insufficient, poll GET /v1/people with a date filter or use POST /v1/people/search with updatedSince filter for change detection.
- Webhook events: employee.created, employee.updated, employee.terminated, employee.start_date_changed, time_off.request.approved, time_off.request.declined
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: All plans (SSO prerequisite required)
Endpoint: https://api.hibob.com/scim/v2
Supported operations: GET /Users, GET /Users/{id}, POST /Users, PUT /Users/{id}, PATCH /Users/{id}, DELETE /Users/{id}, GET /Groups, POST /Groups, PATCH /Groups/{id}, DELETE /Groups/{id}
Limitations:
- SSO must be configured before SCIM provisioning can be enabled
- SCIM token is generated separately from Service User credentials in Settings > Integrations > SCIM
- Group provisioning maps to HiBob departments; not all department attributes are writable via SCIM
- Custom HiBob fields are not exposed via SCIM; use the native REST API for custom field writes
- Supported IdPs with documented integration guides: Okta, Microsoft Entra ID (Azure AD)
Common scenarios
Three API scenarios cover the majority of identity lifecycle operations against HiBob. For onboarding, POST /v1/people with firstName, surname, email, and work.
startDate; capture the returned ID; then PUT /v1/people/{id}/work to set department, title, site, and reportsTo - work history is append-only, so each PUT creates a new dated record rather than overwriting current state.
For bulk sync into an identity graph or external system, POST /v1/people/search with a fields array and status filters, paginate via cursor until no next token is returned, store the HiBob-to-external-ID mapping, and register webhooks for employee. created and employee.
updated - treat webhook delivery as best-effort and run a periodic full sync as a fallback, since webhook payloads are minimal and require a follow-up GET /v1/people/{id} to retrieve full record state.
For termination and deprovisioning, resolve the employee ID via search, POST /v1/people/{id}/employment/terminate with a terminationReason that exactly matches a value pre-configured in HiBob admin, then verify status via GET.
if SCIM is configured with Okta or Entra ID, deprovisioning propagates on the next IdP sync cycle (approximately 40 minutes for Okta).
Onboard a new hire
- POST /v1/people with firstName, surname, email, and work.startDate to create the employee record
- Capture the returned employee ID from the response
- PUT /v1/people/{id}/work to set department, title, site, and reportsTo
- If using SCIM IdP provisioning, the IdP will automatically provision the user's SSO account upon sync
Watch out for: If startDate is in the future, the employee will appear as 'upcoming' and may not be visible in default list queries until their start date. Use showInactive=true or filter by startDate to verify creation.
Sync HiBob employees to an external system
- POST /v1/people/search with desired fields array and any department/status filters
- Paginate through results using the 'next' cursor token until no cursor is returned
- Map HiBob employee IDs to external system identifiers and store the mapping
- Set up a webhook for employee.created and employee.updated events to receive real-time changes
- On webhook receipt, call GET /v1/people/{id} to fetch the full updated record
Watch out for: Webhook payloads are minimal; always fetch the full record via GET after receiving a webhook. Webhook delivery is not guaranteed; implement a periodic full-sync as a fallback.
Terminate an employee and deprovision access
- Resolve the employee's HiBob ID via GET /v1/people or POST /v1/people/search using their email
- POST /v1/people/{id}/employment/terminate with terminationDate and terminationReason
- If SCIM is configured with Okta or Entra ID, the IdP will automatically deprovision the user's SSO and downstream app access upon the next SCIM sync
- Verify deprovisioning by calling GET /v1/people/{id} and confirming employment status is 'Terminated'
Watch out for: terminationReason must match an existing value in HiBob's configured termination reasons list. SCIM deprovisioning sync frequency depends on IdP polling interval (typically 40 minutes for Okta).
Why building this yourself is a trap
Several API behaviors create integration traps that are not obvious from the documentation surface.
Custom fields (work.customColumns) use instance-specific field path names that vary per tenant and must be discovered via the HiBob admin UI or a metadata call - there is no standardized schema across accounts, which breaks any integration that assumes portable field names and makes identity graph enrichment with custom attributes a per-tenant engineering task.
The SCIM endpoint (https://api.hibob.com/scim/v2) uses a separately generated token from the REST API Service User token; they are not interchangeable, and SCIM cannot write custom fields at all, making a hybrid SCIM-plus-REST approach necessary for full identity graph fidelity.
List values for department, site, employment type, and termination reason must pre-exist in HiBob admin - the API rejects unrecognized values rather than creating them, which causes silent failures in automated pipelines if source-system values drift from HiBob's configured list.
Finally, GET /v1/people excludes inactive employees by default; any identity graph reconciliation job that omits showInactive=true will silently miss terminated employees and produce an incomplete picture of historical access.
Automate HiBob workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.