Summary and recommendation
The Sophos Central REST API uses OAuth 2.0 Client Credentials for authentication.
Credentials are role-scoped in Sophos Central - there are no OAuth scopes in the traditional sense;
the admin role assigned to the API credential determines what operations are permitted.
The API is region-partitioned: you must call GET https://api.central.sophos.com/whoami/v1 before any tenant-scoped request to resolve the correct dataRegion base URL (e.g., https://api-{region}.central.sophos.com).
All tenant-scoped requests require both a Bearer token in the Authorization header and the X-Tenant-ID header;
omitting either returns a 400 or 403.
Access tokens expire and must be refreshed by re-requesting via the client_credentials grant against https://id.sophos.com/api/v2/oauth2/token.
Partner/MSP accounts use a separate flow involving X-Organization-ID and are out of scope here.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 Client Credentials |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | N/A |
Authentication
Auth method: OAuth 2.0 Client Credentials
Setup steps
- Log in to Sophos Central as an administrator.
- Navigate to Global Settings > API Credentials Management.
- Click 'Add Credential', provide a name, and select the appropriate role (e.g., Super Admin or Service Principal).
- Copy the generated Client ID and Client Secret.
- POST to https://id.sophos.com/api/v2/oauth2/token with grant_type=client_credentials, client_id, and client_secret to obtain a Bearer token.
- Call GET https://api.central.sophos.com/whoami/v1 to retrieve your tenant ID and the region-specific API host (e.g., https://api-{region}.central.sophos.com).
- Use the region-specific base URL and include the Bearer token in the Authorization header and X-Tenant-ID header for all subsequent requests.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| token (client_credentials grant) | Sophos uses role-based API credentials rather than OAuth scopes. The credential role (e.g., Super Admin, Read Only) determines access. | All API operations |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string (UUID) | Unique identifier for the user in Sophos Central. | system-generated | immutable | Used as path parameter for user-specific operations. |
| name | string | Full display name of the user. | required | optional | |
| firstName | string | User's first name. | optional | optional | |
| lastName | string | User's last name. | optional | optional | |
| string | Primary email address of the user. | required | optional | Must be unique within the tenant. | |
| exchangeLogin | string | Exchange/AD login name associated with the user. | optional | optional | |
| groups | array of objects | List of user groups the user belongs to, each with id and name. | optional | optional | Group membership can be managed separately via group endpoints. |
| tenant | object | Tenant context object containing id. | system-set | immutable | Derived from X-Tenant-ID header. |
| source | object | Indicates the source of the user record (e.g., activeDirectory, azureActiveDirectory, sophosCentral). | system-set | read-only | AD-sourced users may have limited editability via API. |
| createdAt | string (ISO 8601) | Timestamp when the user was created. | system-generated | immutable |
Core endpoints
List users
- Method: GET
- URL:
https://api-{region}.central.sophos.com/common/v1/directory/users - Watch out for: Must resolve region-specific base URL via /whoami/v1 first. Use pageFromKey from pages.nextKey for cursor pagination.
Request example
GET /common/v1/directory/users?pageSize=50
Authorization: Bearer {token}
X-Tenant-ID: {tenantId}
Response example
{
"items": [
{"id":"uuid","name":"Jane Doe","email":"jane@example.com"}
],
"pages": {"size":50,"total":120,"nextKey":"abc123"}
}
Get user by ID
- Method: GET
- URL:
https://api-{region}.central.sophos.com/common/v1/directory/users/{userId} - Watch out for: Returns 404 if user does not exist in the tenant specified by X-Tenant-ID.
Request example
GET /common/v1/directory/users/{userId}
Authorization: Bearer {token}
X-Tenant-ID: {tenantId}
Response example
{
"id": "uuid",
"name": "Jane Doe",
"email": "jane@example.com",
"groups": [{"id":"grp-uuid","name":"Finance"}]
}
Create user
- Method: POST
- URL:
https://api-{region}.central.sophos.com/common/v1/directory/users - Watch out for: Email must be unique per tenant. AD-synced tenants may reject manual user creation for AD-managed users.
Request example
POST /common/v1/directory/users
Authorization: Bearer {token}
X-Tenant-ID: {tenantId}
Content-Type: application/json
{"name":"Jane Doe","email":"jane@example.com"}
Response example
{
"id": "new-uuid",
"name": "Jane Doe",
"email": "jane@example.com"
}
Update user
- Method: PATCH
- URL:
https://api-{region}.central.sophos.com/common/v1/directory/users/{userId} - Watch out for: Users sourced from Active Directory or Azure AD may be read-only via API; updates may be rejected.
Request example
PATCH /common/v1/directory/users/{userId}
Authorization: Bearer {token}
X-Tenant-ID: {tenantId}
Content-Type: application/json
{"name":"Jane Smith"}
Response example
{
"id": "uuid",
"name": "Jane Smith",
"email": "jane@example.com"
}
Delete user
- Method: DELETE
- URL:
https://api-{region}.central.sophos.com/common/v1/directory/users/{userId} - Watch out for: Deleting a user does not automatically remove associated endpoint assignments or policies.
Request example
DELETE /common/v1/directory/users/{userId}
Authorization: Bearer {token}
X-Tenant-ID: {tenantId}
Response example
HTTP 204 No Content
List user groups
- Method: GET
- URL:
https://api-{region}.central.sophos.com/common/v1/directory/user-groups - Watch out for: Group membership changes may take time to propagate to policy enforcement.
Request example
GET /common/v1/directory/user-groups?pageSize=50
Authorization: Bearer {token}
X-Tenant-ID: {tenantId}
Response example
{
"items": [
{"id":"grp-uuid","name":"Finance","description":"Finance team"}
],
"pages": {"size":50,"total":5}
}
Add user to group
- Method: POST
- URL:
https://api-{region}.central.sophos.com/common/v1/directory/user-groups/{groupId}/users - Watch out for: Batch add; invalid user IDs are reported in errors array rather than failing the entire request.
Request example
POST /common/v1/directory/user-groups/{groupId}/users
Authorization: Bearer {token}
X-Tenant-ID: {tenantId}
Content-Type: application/json
{"ids":["user-uuid-1","user-uuid-2"]}
Response example
{
"addedCount": 2,
"errors": []
}
Resolve tenant context (whoami)
- Method: GET
- URL:
https://api.central.sophos.com/whoami/v1 - Watch out for: Must be called before any tenant-scoped API call to obtain the correct dataRegion host. Using the wrong regional host returns 403 or 404.
Request example
GET /whoami/v1
Authorization: Bearer {token}
Response example
{
"id": "tenant-uuid",
"idType": "tenant",
"apiHosts": {
"global": "https://api.central.sophos.com",
"dataRegion": "https://api-us01.central.sophos.com"
}
}
Rate limits, pagination, and events
- Rate limits: Sophos Central API enforces rate limits but does not publicly document specific numeric thresholds per plan in official docs. Exceeding limits returns HTTP 429.
- Rate-limit headers: No
- Retry-After header: No
- Rate-limit notes: Official docs do not specify rate-limit headers or Retry-After behavior. Implement exponential backoff on HTTP 429 responses.
- Pagination method: cursor
- Default page size: 50
- Max page size: 100
- Pagination pointer: pageFromKey
| Plan | Limit | Concurrent |
|---|---|---|
| All plans | Not publicly documented; HTTP 429 returned on breach | 0 |
- Webhooks available: No
- Webhook notes: Sophos Central API does not offer a native webhook/push notification system for user-management events as of the current documentation.
- Alternative event strategy: Poll the directory/users endpoint periodically to detect changes, or use Sophos SIEM integration / event streaming for security events (not user provisioning events).
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: N/A
- Endpoint: Not documented
Limitations:
- Sophos Central does not expose a native SCIM 2.0 endpoint.
- User provisioning from Okta is available via the Okta Sophos connector (SAML/SSO-based provisioning), not a standards-based SCIM endpoint.
- Microsoft Entra ID integration is available for SSO but SCIM provisioning is not documented as natively supported.
Common scenarios
Three core automation scenarios are supported by the directory API.
For provisioning, POST to /common/v1/directory/users to create the user record, then POST to /common/v1/directory/user-groups/{groupId}/users to assign group membership - capture the returned user UUID from the creation response before the group call.
For offboarding, locate the user UUID via GET /common/v1/directory/users?search={email}, then DELETE /common/v1/directory/users/{userId};
note that deletion does not uninstall Sophos agents from the user's devices or revoke active endpoint sessions - endpoint cleanup is a separate operation against the endpoint management API.
For bulk enumeration, use GET /common/v1/directory/users?pageSize=100 and follow the cursor: if pages.nextKey is present in the response, pass it as pageFromKey on the next request;
continue until pages.nextKey is absent.
Cursor values are opaque strings - do not attempt to construct or increment them.
For identity graph use cases, the user object exposes source (indicating activeDirectory, azureActiveDirectory, or sophosCentral origin), exchangeLogin, groups array, and tenant context, giving you the fields needed to correlate Sophos user records against upstream identity providers in a unified identity graph.
Provision a new user and assign to a group
- POST to https://id.sophos.com/api/v2/oauth2/token to obtain Bearer token.
- GET https://api.central.sophos.com/whoami/v1 to retrieve tenantId and dataRegion host.
- POST to https://api-{region}.central.sophos.com/common/v1/directory/users with name and email to create the user; capture returned id.
- GET https://api-{region}.central.sophos.com/common/v1/directory/user-groups to find the target group UUID.
- POST to https://api-{region}.central.sophos.com/common/v1/directory/user-groups/{groupId}/users with {"ids":["new-user-uuid"]} to add user to group.
Watch out for: If the tenant uses AD sync, the user may need to be created in AD first and will appear in Sophos after sync; direct API creation may be rejected.
Deprovision a user (offboarding)
- Obtain Bearer token and resolve dataRegion via /whoami/v1.
- GET /common/v1/directory/users?search={email} to locate the user's UUID.
- DELETE /common/v1/directory/users/{userId} to remove the user from Sophos Central.
- Verify endpoint devices previously assigned to the user are reassigned or decommissioned via the endpoint management API separately.
Watch out for: Deleting the user record does not automatically uninstall Sophos agents from their devices or revoke active sessions; endpoint cleanup is a separate operation.
Bulk list all users with pagination
- Obtain Bearer token and resolve dataRegion via /whoami/v1.
- GET /common/v1/directory/users?pageSize=100 - process items array.
- If pages.nextKey is present in the response, repeat GET /common/v1/directory/users?pageSize=100&pageFromKey={nextKey}.
- Continue until pages.nextKey is absent or null.
Watch out for: pageFromKey values are opaque cursor strings; do not attempt to construct or increment them manually.
Why building this yourself is a trap
Several non-obvious constraints will break integrations if not handled upfront. Users synchronized from Active Directory or Azure AD are typically read-only via the REST API; create, update, and delete operations on AD-sourced users may return 400 or 409 - for AD-managed tenants, user lifecycle must be driven from the directory, not from Sophos.
Sophos Central has no native SCIM 2.0 endpoint; the Okta connector uses SAML/SSO-based provisioning, not a standards-based SCIM flow, so any SCIM assumptions in your tooling will not apply. Rate limits are not publicly documented - the API returns HTTP 429 on breach with no Retry-After header, so implement exponential backoff unconditionally.
Finally, deleting an admin account that owns active API credentials immediately invalidates those tokens; any integration running under that credential will fail silently until re-credentialed.
Automate Sophos 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.