Summary and recommendation
Hex exposes user and group lifecycle management exclusively through a SCIM 2.0 API surface at https://app.hex.tech/api/v1/scim/v2, gated behind the Enterprise plan.
Authentication uses a dedicated SCIM bearer token generated separately from the general Hex API key at Settings → Authentication → SCIM - passing the wrong token returns a 401.
The general REST API at /api/v1 covers project runs and status only;
it is a distinct surface and must not be conflated with the SCIM user-management interface.
No outbound webhooks are documented for user-management events;
polling the SCIM /Users endpoint or relying on IdP-side event logs is the documented alternative for provisioning audit trails.
Supported SCIM operations include GET, POST, PUT, PATCH, and DELETE on /Users, and GET, POST, PATCH, and DELETE on /Groups.
Pagination uses a 1-based startIndex cursor parameter - not a 0-based offset - with no documented default or maximum page size in official sources.
Rate limits are not publicly documented;
implement exponential backoff defensively on all requests.
For identity graph construction, the user object exposes both a Hex-assigned internal id and an IdP-supplied externalId, enabling bidirectional correlation between the Hex workspace identity and the upstream IdP record.
The userName field maps to the user's primary email address and is the correct filter key for lookups (filter=userName eq "user@example.com").
Group membership in SCIM responses surfaces as an array on the user object, providing a direct edge from user to workspace group without a secondary lookup.
API quick reference
| Has user API | Yes |
| Auth method | Bearer token (API key) |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Enterprise |
Authentication
Auth method: Bearer token (API key)
Setup steps
- Log in to Hex as a workspace admin.
- Navigate to Settings → API keys.
- Generate a new API key; copy the token immediately (it is shown only once).
- For SCIM, navigate to Settings → Authentication → SCIM and generate a dedicated SCIM bearer token.
- Pass the token in the Authorization header: 'Authorization: Bearer
'.
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Hex-assigned unique identifier for the user (SCIM 'id'). | server-assigned | read-only | Returned by Hex; not supplied by the client. |
| userName | string | The user's email address, used as the SCIM userName. | required | supported | Must be a valid email; serves as the primary unique identifier from the IdP side. |
| name.givenName | string | User's first name. | optional | supported | Part of the SCIM 'name' complex attribute. |
| name.familyName | string | User's last name. | optional | supported | Part of the SCIM 'name' complex attribute. |
| emails | array | List of email objects; primary email used for account matching. | required | supported | At least one entry with 'primary: true' expected. |
| active | boolean | Whether the user account is active in the Hex workspace. | optional (defaults true) | supported | Setting to false deprovisions the user without deleting them. |
| externalId | string | Identifier assigned by the IdP for correlation. | optional | supported | Used by the IdP to track the user; stored by Hex for reconciliation. |
| groups | array | Groups the user belongs to (read from Hex in User responses). | read-only in user object | managed via Group endpoints | Group membership is managed through SCIM Group endpoints, not directly on the user object. |
Core endpoints
List Users
- Method: GET
- URL:
https://app.hex.tech/api/v1/scim/v2/Users - Watch out for: Uses SCIM-standard 1-based startIndex, not 0-based offset.
Request example
GET /api/v1/scim/v2/Users?startIndex=1&count=20
Authorization: Bearer <scim_token>
Response example
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 42,
"startIndex": 1,
"itemsPerPage": 20,
"Resources": [{...}]
}
Get User
- Method: GET
- URL:
https://app.hex.tech/api/v1/scim/v2/Users/{id} - Watch out for: Use the Hex-assigned 'id', not the IdP externalId, in the path.
Request example
GET /api/v1/scim/v2/Users/abc123
Authorization: Bearer <scim_token>
Response example
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "abc123",
"userName": "user@example.com",
"active": true
}
Create User
- Method: POST
- URL:
https://app.hex.tech/api/v1/scim/v2/Users - Watch out for: Creating a user who already exists by email may return a conflict error rather than silently updating.
Request example
POST /api/v1/scim/v2/Users
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "user@example.com",
"name": {"givenName": "Jane", "familyName": "Doe"},
"active": true
}
Response example
{
"id": "abc123",
"userName": "user@example.com",
"active": true
}
Update User (full replace)
- Method: PUT
- URL:
https://app.hex.tech/api/v1/scim/v2/Users/{id} - Watch out for: PUT replaces the full user object; omitting fields may clear them.
Request example
PUT /api/v1/scim/v2/Users/abc123
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "user@example.com",
"active": true
}
Response example
{
"id": "abc123",
"userName": "user@example.com",
"active": true
}
Update User (partial patch)
- Method: PATCH
- URL:
https://app.hex.tech/api/v1/scim/v2/Users/{id} - Watch out for: Primary use case is deactivating users (active=false) without deleting them.
Request example
PATCH /api/v1/scim/v2/Users/abc123
Content-Type: application/scim+json
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [{"op": "replace", "path": "active", "value": false}]
}
Response example
{
"id": "abc123",
"userName": "user@example.com",
"active": false
}
Delete User
- Method: DELETE
- URL:
https://app.hex.tech/api/v1/scim/v2/Users/{id} - Watch out for: Prefer PATCH active=false for deprovisioning; DELETE may permanently remove workspace data associations.
Request example
DELETE /api/v1/scim/v2/Users/abc123
Authorization: Bearer <scim_token>
Response example
HTTP 204 No Content
List Groups
- Method: GET
- URL:
https://app.hex.tech/api/v1/scim/v2/Groups - Watch out for: Groups in Hex map to workspace groups; group membership controls project access.
Request example
GET /api/v1/scim/v2/Groups
Authorization: Bearer <scim_token>
Response example
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 3,
"Resources": [{"id": "grp1", "displayName": "Analysts"}]
}
Patch Group (add/remove members)
- Method: PATCH
- URL:
https://app.hex.tech/api/v1/scim/v2/Groups/{id} - Watch out for: Member 'value' must be the Hex SCIM user 'id', not the email or externalId.
Request example
PATCH /api/v1/scim/v2/Groups/grp1
Content-Type: application/scim+json
{
"Operations": [{"op": "add", "path": "members",
"value": [{"value": "abc123"}]}]
}
Response example
HTTP 204 No Content
Rate limits, pagination, and events
Rate limits: Hex does not publicly document specific rate-limit numbers or tiers in its official docs as of the policy date.
Rate-limit headers: No
Retry-After header: No
Rate-limit notes: No rate-limit figures, headers, or Retry-After behavior are documented in official Hex sources.
Pagination method: cursor
Default page size: 0
Max page size: 0
Pagination pointer: startIndex
Webhooks available: No
Webhook notes: Hex does not document outbound webhooks for user-management events in official sources.
Alternative event strategy: Poll SCIM /Users endpoint or use IdP-side event logs for provisioning audit trails.
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Enterprise
Endpoint: https://app.hex.tech/api/v1/scim/v2
Supported operations: GET /Users (list), GET /Users/{id}, POST /Users, PUT /Users/{id}, PATCH /Users/{id}, DELETE /Users/{id}, GET /Groups, GET /Groups/{id}, POST /Groups, PATCH /Groups/{id}, DELETE /Groups/{id}
Limitations:
- SCIM provisioning requires the Enterprise plan.
- A dedicated SCIM bearer token must be generated separately from general API keys.
- Role assignment (e.g., Viewer vs. Editor) via SCIM is not explicitly documented; role management may require manual admin action.
- No official documentation of supported SCIM filter operators beyond basic userName filtering.
- IdP-specific app gallery connectors (Okta, Entra ID) are not listed as pre-built integrations in official docs; generic SCIM 2.0 connector must be configured manually.
Common scenarios
Three scenarios cover the primary lifecycle operations against the SCIM surface.
Provisioning a new employee: POST to /api/v1/scim/v2/Users with userName (email), name.givenName, name.familyName, and active=true.
Capture the returned Hex id immediately - it is required for all subsequent PATCH and group operations.
Before posting, check for an existing record with GET /Users?filter=userName eq "email";
a duplicate POST may return a 409 Conflict rather than a silent upsert.
Deprovisioning a departing employee: Retrieve the Hex SCIM id via GET /Users?filter=userName eq "user@example.com", then PATCH /Users/{id} with Operations: [{op: replace, path: active, value: false}].
Prefer this over DELETE - deactivation via active=false is reversible, while DELETE may permanently sever workspace data associations with no documented recovery path.
Syncing a new IdP group: POST to /api/v1/scim/v2/Groups with the target displayName, ensure all intended members are already provisioned as Hex users, then PATCH the group with an add members operation.
All member value references must use the Hex internal SCIM id - not the IdP user ID, externalId, or email address - or the operation will fail.
Provision a new employee
- Obtain the SCIM bearer token from Hex workspace Settings → Authentication → SCIM.
- POST to /api/v1/scim/v2/Users with userName (email), name.givenName, name.familyName, and active=true.
- Capture the returned Hex 'id' for future updates.
- If the user should belong to a group, PATCH /api/v1/scim/v2/Groups/{groupId} with an 'add members' operation referencing the new user's 'id'.
Watch out for: If the email already exists in the workspace, the POST may return a 409 Conflict; check for existing users with GET /Users?filter=userName eq "email" first.
Deprovision a departing employee
- Retrieve the user's Hex SCIM 'id' via GET /api/v1/scim/v2/Users?filter=userName eq "user@example.com".
- PATCH /api/v1/scim/v2/Users/{id} with Operations: [{op: replace, path: active, value: false}].
- Optionally remove from all groups via PATCH on each Group with a 'remove members' operation.
Watch out for: Prefer PATCH active=false over DELETE to preserve audit history and avoid unrecoverable data loss.
Sync a new team group from IdP
- POST to /api/v1/scim/v2/Groups with displayName matching the IdP group name.
- Ensure all group members are already provisioned as Hex users (POST /Users if not).
- PATCH the new group with an 'add members' operation listing each member's Hex SCIM 'id'.
- Verify membership with GET /api/v1/scim/v2/Groups/{id}.
Watch out for: Member references must use Hex's internal SCIM 'id' values, not IdP user IDs or email addresses.
Why building this yourself is a trap
The most consequential caveat in Hex's SCIM implementation is role assignment: assigning Editor versus Viewer seat type via SCIM is not explicitly documented, meaning automated provisioning may land users in a default role that requires a subsequent manual admin correction. This creates a gap in fully automated lifecycle management even on Enterprise.
Additionally, no pre-built IdP app gallery connectors (Okta, Entra ID) are listed in official documentation; teams must configure a generic SCIM 2.0 connector manually, which increases setup complexity and the risk of misconfiguration.
Finally, because Hex exposes no webhooks on the user-management surface, any system that needs to react to provisioning events such as a downstream identity graph that tracks Hex workspace membership alongside other SaaS identities must poll the SCIM /Users endpoint on a schedule rather than receiving push notifications, adding latency to access state synchronization.
Automate Hex 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.