Summary and recommendation
QRadar exposes user management through its REST API under `/api/config/access/users`.
Authentication uses a SEC token (authorized service token) passed as an HTTP header - Basic Auth is supported but not recommended for automation.
Every API request must include a `Version` header specifying the target API version (e.g., `Version: 21.0`);
omitting it may silently fall back to an older default.
The API is on-premises only.
There is no shared SaaS endpoint - the base URL is always the customer's own QRadar Console hostname.
Self-signed TLS certificates are common;
API clients must handle certificate validation explicitly.
No SCIM 2.0 endpoint is available natively;
identity graph integrations that require SCIM must use the REST API as a backend, typically via a third-party connector layer.
Pagination is controlled via the HTTP `Range` header (e.g., `Range: items=0-49`), not query parameters.
IBM does not publish explicit rate-limit thresholds;
limits are governed by appliance resources, and tight polling loops are explicitly discouraged.
API quick reference
| Has user API | Yes |
| Auth method | SEC token (authorized service token) or HTTP Basic Auth (username:password). SEC token is the recommended method for programmatic access. |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | N/A |
Authentication
Auth method: SEC token (authorized service token) or HTTP Basic Auth (username:password). SEC token is the recommended method for programmatic access.
Setup steps
- Log in to the QRadar Console as an admin.
- Navigate to Admin > Authorized Services.
- Click 'Add Authorized Service', provide a name, assign a security profile and user role.
- Copy the generated token (SEC token).
- Include the token in all API requests as the HTTP header: SEC:
. - Alternatively, use HTTP Basic Auth with Authorization: Basic <base64(user:password)> header, though this is less recommended for automation.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| User Role: Admin | Full administrative access including user management endpoints. | Creating, updating, and deleting users via /config/access/users |
| Security Profile assignment | Each authorized service token is bound to a security profile controlling which data domains are accessible. | Scoping data access for the token used in API calls |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | integer | Unique identifier for the user. | system-assigned | read-only | Used as path parameter in user-specific endpoints. |
| username | string | Login username for the QRadar user. | required | optional | Must be unique within the deployment. |
| string | Email address of the user. | optional | optional | ||
| password | string | User password (write-only). | required | optional | Never returned in GET responses. |
| first_name | string | User's first name. | optional | optional | |
| last_name | string | User's last name. | optional | optional | |
| user_role | object | Role assigned to the user, controlling permissions within QRadar. | required | optional | Contains id and name fields. Roles are managed separately via /config/access/roles. |
| security_profile | object | Security profile controlling which networks and log sources the user can access. | required | optional | Contains id and name fields. Profiles managed via /config/access/security_profiles. |
| tenant_id | integer | Tenant identifier in multi-tenant deployments. | optional | optional | Relevant only in QRadar multi-tenant (MSSP) configurations. |
| description | string | Optional description for the user account. | optional | optional | |
| locale_id | string | Locale/language preference for the user. | optional | optional | |
| inactivity_timeout | integer | Session inactivity timeout in minutes. | optional | optional |
Core endpoints
List all users
- Method: GET
- URL:
/api/config/access/users - Watch out for: Pagination is controlled via the Range HTTP header, not query parameters. Omitting Range returns a default page.
Request example
GET /api/config/access/users HTTP/1.1
Host: <qradar-host>
SEC: <token>
Version: 21.0
Range: items=0-49
Response example
[
{
"id": 1001,
"username": "jdoe",
"email": "jdoe@example.com",
"first_name": "John",
"last_name": "Doe",
"user_role": {"id": 2, "name": "Analyst"}
}
]
Get a specific user
- Method: GET
- URL:
/api/config/access/users/{id} - Watch out for: Password field is never returned in GET responses.
Request example
GET /api/config/access/users/1001 HTTP/1.1
Host: <qradar-host>
SEC: <token>
Version: 21.0
Response example
{
"id": 1001,
"username": "jdoe",
"email": "jdoe@example.com",
"first_name": "John",
"last_name": "Doe",
"user_role": {"id": 2, "name": "Analyst"},
"security_profile": {"id": 1, "name": "Default"}
}
Create a user
- Method: POST
- URL:
/api/config/access/users - Watch out for: user_role and security_profile are required on creation. Role and profile IDs must be retrieved beforehand from their respective endpoints.
Request example
POST /api/config/access/users HTTP/1.1
Host: <qradar-host>
SEC: <token>
Version: 21.0
Content-Type: application/json
{"username":"jsmith","password":"P@ssw0rd!","email":"jsmith@example.com","user_role":{"id":2},"security_profile":{"id":1}}
Response example
{
"id": 1002,
"username": "jsmith",
"email": "jsmith@example.com",
"user_role": {"id": 2, "name": "Analyst"},
"security_profile": {"id": 1, "name": "Default"}
}
Update a user
- Method: POST
- URL:
/api/config/access/users/{id} - Watch out for: QRadar uses POST (not PATCH or PUT) for updating an existing user by ID. Only fields included in the body are updated.
Request example
POST /api/config/access/users/1002 HTTP/1.1
Host: <qradar-host>
SEC: <token>
Version: 21.0
Content-Type: application/json
{"email":"jsmith.new@example.com","user_role":{"id":3}}
Response example
{
"id": 1002,
"username": "jsmith",
"email": "jsmith.new@example.com",
"user_role": {"id": 3, "name": "Admin"}
}
Delete a user
- Method: DELETE
- URL:
/api/config/access/users/{id} - Watch out for: DELETE is asynchronous and returns a task ID. Poll /api/config/access/users/delete_tasks/{task_id} to confirm completion.
Request example
DELETE /api/config/access/users/1002 HTTP/1.1
Host: <qradar-host>
SEC: <token>
Version: 21.0
Response example
HTTP/1.1 202 Accepted
{"task_id": 5678}
List user roles
- Method: GET
- URL:
/api/config/access/roles - Watch out for: Role IDs are required when creating or updating users. Role names are not accepted directly in user payloads.
Request example
GET /api/config/access/roles HTTP/1.1
Host: <qradar-host>
SEC: <token>
Version: 21.0
Response example
[
{"id": 1, "name": "Admin"},
{"id": 2, "name": "Analyst"},
{"id": 3, "name": "Reader"}
]
List security profiles
- Method: GET
- URL:
/api/config/access/security_profiles - Watch out for: Security profile IDs must be resolved before user creation. Profiles control data domain visibility, not just permissions.
Request example
GET /api/config/access/security_profiles HTTP/1.1
Host: <qradar-host>
SEC: <token>
Version: 21.0
Response example
[
{"id": 1, "name": "Default"},
{"id": 2, "name": "SOC Team"}
]
List authorized services (API tokens)
- Method: GET
- URL:
/api/config/access/authorized_services - Watch out for: Authorized service tokens are separate from user accounts. Token values are only shown at creation time via the UI; the API returns them in GET responses but this may vary by version.
Request example
GET /api/config/access/authorized_services HTTP/1.1
Host: <qradar-host>
SEC: <token>
Version: 21.0
Response example
[
{
"id": 10,
"name": "Automation Service",
"token": "<sec-token-value>",
"user_role": {"id": 1, "name": "Admin"}
}
]
Rate limits, pagination, and events
Rate limits: IBM QRadar REST API documentation does not explicitly publish rate limit thresholds or per-plan tiers. Limits are governed by the underlying QRadar appliance/VM resources. Concurrent request limits exist but are not documented with specific numbers in official docs.
Rate-limit headers: No
Retry-After header: No
Rate-limit notes: No explicit rate-limit headers or Retry-After behavior documented in official IBM sources. Heavy API usage may be throttled by the appliance. IBM recommends avoiding tight polling loops.
Pagination method: offset
Default page size: 50
Max page size: 0
Pagination pointer: Range (HTTP header, e.g. Range: items=0-49)
Webhooks available: No
Webhook notes: IBM QRadar does not provide a native outbound webhook system for user-management events. Event-driven integrations are typically achieved via the QRadar SIEM offense/event pipeline or custom apps using the QRadar App Framework.
Alternative event strategy: Use QRadar's Custom Actions or App Framework to trigger external HTTP calls based on SIEM events. For user-change auditing, query the audit log via /api/system/information or syslog forwarding.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: N/A
- Endpoint: Not documented
Limitations:
- QRadar does not natively expose a SCIM 2.0 endpoint.
- LDAP/Active Directory integration is available for authentication federation but is not SCIM-based.
- Third-party identity governance tools may provide SCIM-to-QRadar connectors using the REST API as a backend.
Common scenarios
Provisioning a new user requires three sequential API calls before the POST: resolve the target role ID from GET /api/config/access/roles, resolve the security profile ID from GET /api/config/access/security_profiles, then POST to /api/config/access/users with both IDs in the body.
Submitting role or profile names instead of integer IDs returns a 422 error.
Updating a user's role uses POST /api/config/access/users/{id} - not PATCH or PUT, which are unsupported on this endpoint.
Only fields included in the request body are modified;
omitted fields are left unchanged.
Deprovisioning is asynchronous.
DELETE /api/config/access/users/{id} returns a 202 with a task_id.
Downstream provisioning workflows must poll GET /api/config/access/users/delete_tasks/{task_id} until status is COMPLETED before treating the user as removed.
Assuming synchronous deletion causes race conditions.
Authorized service tokens (SEC tokens) are not automatically revoked on user deletion and must be removed separately via /api/config/access/authorized_services.
Provision a new analyst user
- GET /api/config/access/roles to retrieve the ID for the 'Analyst' role.
- GET /api/config/access/security_profiles to retrieve the appropriate security profile ID.
- POST /api/config/access/users with username, password, email, user_role.id, and security_profile.id in the request body.
- Store the returned user id for future reference.
Watch out for: Role and security profile IDs must be resolved before the POST. Submitting role/profile names instead of IDs will result in a 422 error.
Update a user's role
- GET /api/config/access/users to find the target user's id by username.
- GET /api/config/access/roles to confirm the new role's id.
- POST /api/config/access/users/{id} with only the updated user_role object in the body.
Watch out for: Using POST for updates is non-standard. Do not use PUT or PATCH - they are not supported for this endpoint.
Deprovision a user and confirm deletion
- GET /api/config/access/users?filter=username%3D%22jsmith%22 to retrieve the user's id.
- DELETE /api/config/access/users/{id} and capture the task_id from the 202 response.
- Poll GET /api/config/access/users/delete_tasks/{task_id} until status is 'COMPLETED'.
- Optionally verify by attempting GET /api/config/access/users/{id} and confirming a 404 response.
Watch out for: DELETE is asynchronous. Assuming immediate deletion without polling the task can cause race conditions in downstream provisioning workflows.
Why building this yourself is a trap
The non-standard update verb (POST instead of PATCH/PUT) is the most common integration breakage point. Generic REST clients and identity graph connectors that assume standard HTTP semantics will silently fail or hit unexpected errors on user update calls.
SEC tokens are bound to a specific security profile and user role at creation time. There is no in-place permission update for a token - changing its scope requires deleting the authorized service and recreating it, which invalidates any stored token references in downstream systems.
Webhooks are not available. Event-driven user-change detection requires either polling the audit log endpoint or implementing a custom app via the QRadar App Framework.
For identity graph pipelines that depend on push-based change events, this means polling is the only supported integration pattern, and polling frequency must be tuned against appliance resource constraints that IBM does not document with specific numbers.
Automate IBM QRadar 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.