Summary and recommendation
Culture Amp exposes a REST API at `https://api.cultureamp.com/v1` and a separate GraphQL endpoint at `https://api.cultureamp.com/graphql`, with partially overlapping data models between the two. Authentication uses a Bearer token API key generated from Settings > Integrations > API Access; the key is shown only once and is account-scoped.
Required scopes for full employee lifecycle management are `read:employees`, `write:employees`, and `read:groups`.
SCIM is explicitly not supported. The API is the only programmatic provisioning path outside of HRIS integrations, making it the integration layer for any identity graph that needs to reflect Culture Amp employee state. Pagination is cursor-based (`cursor` param, default 100, max 500 per page); do not use offset-based pagination as it is not supported.
Rate limits are not publicly documented; the API returns HTTP 429 with a `Retry-After` header when limits are hit. Implement exponential backoff on all retry logic. Contact Culture Amp support for account-specific rate limit details.
API quick reference
| Has user API | Yes |
| Auth method | API Key (Bearer token in Authorization header) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | Enterprise |
Authentication
Auth method: API Key (Bearer token in Authorization header)
Setup steps
- Log in to Culture Amp as an Account Administrator.
- Navigate to Settings > Integrations > API Access.
- Generate an API key for your integration.
- Store the key securely; it is shown only once.
- Include the key in all requests as: Authorization: Bearer
Required scopes
| Scope | Description | Required for |
|---|---|---|
| read:employees | Read employee profile data | List and retrieve employee records |
| write:employees | Create and update employee records | Provisioning and updating users |
| read:groups | Read group/department data | Fetching organizational structure |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Unique Culture Amp employee identifier | system-generated | immutable | UUID format |
| string | Primary email address | required | optional | Used as login identifier | |
| first_name | string | Employee first name | required | optional | |
| last_name | string | Employee last name | required | optional | |
| preferred_name | string | Preferred display name | optional | optional | |
| employee_id | string | External HR system employee ID | optional | optional | Used for HRIS matching |
| status | string | Employment status (active, inactive) | optional | optional | Deactivating removes platform access |
| department | string | Department name | optional | optional | Used for group segmentation |
| team | string | Team name within department | optional | optional | |
| job_title | string | Employee job title | optional | optional | |
| location | string | Office or geographic location | optional | optional | |
| manager_id | string | Culture Amp ID of the employee's manager | optional | optional | References another employee id |
| start_date | date | Employment start date (ISO 8601) | optional | optional | Affects tenure-based analytics |
| end_date | date | Employment end date (ISO 8601) | optional | optional | Setting this deactivates the employee |
| gender | string | Gender demographic field | optional | optional | Used for DEI reporting |
| custom_fields | object | Account-defined custom demographic attributes | optional | optional | Keys vary per account configuration |
Core endpoints
List Employees
- Method: GET
- URL:
https://api.cultureamp.com/v1/employees - Watch out for: Pagination is cursor-based; do not use offset. Iterate until next_cursor is null.
Request example
GET /v1/employees?cursor=abc123&limit=100
Authorization: Bearer <api_key>
Response example
{
"data": [{"id":"emp_123","email":"jane@acme.com","first_name":"Jane","last_name":"Doe","status":"active"}],
"next_cursor": "def456"
}
Get Employee
- Method: GET
- URL:
https://api.cultureamp.com/v1/employees/{id} - Watch out for: Use Culture Amp's internal id, not employee_id (external HR ID).
Request example
GET /v1/employees/emp_123
Authorization: Bearer <api_key>
Response example
{
"id": "emp_123",
"email": "jane@acme.com",
"first_name": "Jane",
"last_name": "Doe",
"department": "Engineering",
"status": "active"
}
Create Employee
- Method: POST
- URL:
https://api.cultureamp.com/v1/employees - Watch out for: Creating an employee does not automatically send an invitation email unless configured in account settings.
Request example
POST /v1/employees
Authorization: Bearer <api_key>
Content-Type: application/json
{"email":"new@acme.com","first_name":"New","last_name":"User"}
Response example
{
"id": "emp_456",
"email": "new@acme.com",
"first_name": "New",
"last_name": "User",
"status": "active"
}
Update Employee
- Method: PATCH
- URL:
https://api.cultureamp.com/v1/employees/{id} - Watch out for: Only include fields to change; omitted fields are not cleared.
Request example
PATCH /v1/employees/emp_456
Authorization: Bearer <api_key>
Content-Type: application/json
{"department":"Product","job_title":"PM"}
Response example
{
"id": "emp_456",
"department": "Product",
"job_title": "PM"
}
Deactivate Employee
- Method: PATCH
- URL:
https://api.cultureamp.com/v1/employees/{id} - Watch out for: Deactivation removes platform access but does not delete historical survey data. Hard delete is not available via API.
Request example
PATCH /v1/employees/emp_456
Authorization: Bearer <api_key>
Content-Type: application/json
{"status":"inactive","end_date":"2025-06-01"}
Response example
{
"id": "emp_456",
"status": "inactive",
"end_date": "2025-06-01"
}
List Groups
- Method: GET
- URL:
https://api.cultureamp.com/v1/groups - Watch out for: Groups are derived from employee demographic fields; they cannot be created independently via API.
Request example
GET /v1/groups
Authorization: Bearer <api_key>
Response example
{
"data": [{"id":"grp_1","name":"Engineering","type":"department"}]
}
Bulk Import Employees (CSV/SFTP)
- Method: POST
- URL:
https://api.cultureamp.com/v1/imports/employees - Watch out for: Import is asynchronous; poll import_id for completion status. Errors are reported per-row in the import result.
Request example
POST /v1/imports/employees
Authorization: Bearer <api_key>
Content-Type: multipart/form-data
[CSV file attachment]
Response example
{
"import_id": "imp_789",
"status": "processing",
"created": 0,
"updated": 0
}
GraphQL Query (Employee Data)
- Method: POST
- URL:
https://api.cultureamp.com/graphql - Watch out for: GraphQL endpoint is separate from REST. Not all REST fields are exposed in the GraphQL schema; verify schema introspection for available fields.
Request example
POST /graphql
Authorization: Bearer <api_key>
{"query":"{ employees { id email firstName lastName department } }"}
Response example
{
"data": {
"employees": [{"id":"emp_123","email":"jane@acme.com","firstName":"Jane","lastName":"Doe","department":"Engineering"}]
}
}
Rate limits, pagination, and events
- Rate limits: Culture Amp enforces rate limits on API requests; exact published limits are not publicly documented as of early 2025.
- Rate-limit headers: Yes
- Retry-After header: Yes
- Rate-limit notes: When rate limited, the API returns HTTP 429. Retry-After header is included. Implement exponential backoff. Contact Culture Amp support for specific tier limits.
- Pagination method: cursor
- Default page size: 100
- Max page size: 500
- Pagination pointer: cursor
| Plan | Limit | Concurrent |
|---|---|---|
| All plans | Not publicly documented | 0 |
- Webhooks available: No
- Webhook notes: Culture Amp does not publicly document outbound webhooks for user/employee lifecycle events as of early 2025. Employee data changes are managed via HRIS integrations or API polling.
- Alternative event strategy: Use HRIS integrations (BambooHR, Workday, etc.) for real-time employee data sync, or poll the REST API on a schedule.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: Enterprise
- Endpoint: Not documented
Limitations:
- Culture Amp explicitly does not support SCIM provisioning.
- SSO (SAML 2.0) is supported via Okta, Entra ID, Google Workspace, and OneLogin for authentication only.
- Employee data management is handled via HRIS integrations or the REST/GraphQL API, not SCIM.
- Deprovisioning must be done manually or via API/HRIS sync.
Common scenarios
Provisioning a new employee: POST /v1/employees with email, first_name, last_name, department, manager_id, and start_date. Store the returned Culture Amp id - all subsequent updates and deactivations reference this internal ID, not the external employee_id. For rehires, check for an existing inactive record first and reactivate via PATCH status=active rather than creating a duplicate.
Syncing org changes: PATCH /v1/employees/{id} with only the changed fields (department, job_title, manager_id). Group membership in Culture Amp is derived automatically from employee demographic fields and cannot be managed as independent objects - updating the field on the employee record is sufficient. Maintain a mapping table between HRIS IDs and Culture Amp internal IDs, as manager_id references the Culture Amp id, not the external HR system ID.
Offboarding: PATCH /v1/employees/{id} with status=inactive and end_date (ISO 8601). Hard delete is not available via API; historical survey data is retained. SSO session revocation is not triggered by deactivation - revoke the session in the IdP (Okta, Entra, etc.) as a separate step to fully terminate access.
Provision a new employee from HRIS
- POST /v1/employees with email, first_name, last_name, department, manager_id, start_date.
- Store the returned Culture Amp id for future updates.
- Verify account settings to confirm whether an invitation email is sent automatically or must be triggered separately.
Watch out for: If the email already exists (e.g., rehire), the API may return a conflict error. Check for existing inactive records and reactivate via PATCH status=active instead of creating a new record.
Sync organizational changes (department/manager updates)
- Receive change event from HRIS (webhook or scheduled export).
- PATCH /v1/employees/{id} with updated department, job_title, or manager_id fields.
- Confirm response reflects updated values; no additional steps required for group membership as groups are derived automatically.
Watch out for: Manager references use Culture Amp's internal id, not the external employee_id. Maintain a mapping table between HRIS IDs and Culture Amp IDs.
Offboard a departing employee
- PATCH /v1/employees/{id} with status=inactive and end_date set to the last working day (ISO 8601).
- Confirm the employee no longer appears in active employee lists.
- Historical survey responses are retained and remain accessible to admins for reporting.
Watch out for: Deactivation does not revoke SSO sessions immediately if SSO is configured; revoke the SSO session in the IdP (Okta, Entra, etc.) separately.
Why building this yourself is a trap
The most significant architectural caveat is the dual-endpoint model: the REST API and GraphQL API are separate surfaces with partially overlapping schemas. Fields available via REST are not guaranteed to be present in the GraphQL schema; run schema introspection before building any GraphQL-based identity graph queries to avoid silent data gaps.
Custom demographic fields vary per Culture Amp account. Always retrieve the account schema programmatically before mapping fields - hardcoding field names against one account's configuration will break in multi-tenant or multi-account deployments.
Bulk imports via POST /v1/imports/employees are asynchronous; always poll the import_id status endpoint before treating an import as complete, as errors are reported per-row in the result payload and not surfaced synchronously.
Webhooks for employee lifecycle events are not publicly documented as of early 2025. Any identity graph that needs near-real-time Culture Amp state must rely on scheduled API polling or an upstream HRIS webhook feeding changes into the Culture Amp API - there is no native push mechanism from Culture Amp itself.
Automate Culture Amp 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.