Summary and recommendation
Jenkins exposes a remote access API over HTTP using Basic Auth with an API token (username + token, Base64-encoded). There is no native SCIM 2.0 endpoint, no dedicated JSON REST API for user CRUD, and no outbound webhooks for user lifecycle events.
User creation and deletion use form-based POST endpoints that return HTTP 302 redirects rather than JSON responses, requiring redirect-handling or a follow-up GET to confirm state.
All POST requests require a Jenkins-Crumb header fetched from /crumbIssuer/api/json unless the caller is using an API token on Jenkins >= 2.176.2, where API token requests are CSRF-exempt by default.
Integrating Jenkins into an identity graph requires polling - /asynchPeople/api/json for build-active users and /role-strategy/strategy/getAllRoles for role-to-SID mappings - because no push mechanism exists for user management events.
API quick reference
| Has user API | Yes |
| Auth method | HTTP Basic Auth (username + API token) or API token as Bearer token in some contexts |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | N/A |
Authentication
Auth method: HTTP Basic Auth (username + API token) or API token as Bearer token in some contexts
Setup steps
- Log in to Jenkins as the target user.
- Navigate to User > Configure (http://
/user/ /configure). - Under 'API Token', click 'Add new Token', name it, and click 'Generate'.
- Copy the generated token immediately - it is shown only once.
- Use the token as the password in HTTP Basic Auth: Authorization: Basic base64(
: ). - Alternatively, pass the token as a query parameter: ?token=
for some endpoints. - For CSRF protection, fetch a crumb first: GET /crumbIssuer/api/json and include Jenkins-Crumb header in POST requests.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| Overall/Administer | Full administrative access including user creation, deletion, and security configuration. | Creating/deleting users, modifying security realm settings. |
| Overall/Read | Read access to Jenkins instance. | Listing users, reading user metadata. |
| Overall/SystemRead | Read-only access to system configuration. | Reading security and user configuration without modification. |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| id | string | Unique username/login identifier. | required | immutable | Used as the URL path segment: /user/ |
| fullName | string | Display name of the user. | optional | settable | Returned in user JSON responses. |
| description | string | Free-text description of the user. | optional | settable | |
| absoluteUrl | string | Full URL to the user's profile page. | auto | read-only | Derived from base URL and user id. |
| property | array | Array of user property objects (e.g., email, API tokens, timezone). | optional | settable via separate endpoints | Includes hudson.tasks.Mailer$UserProperty for email address. |
| string | User's email address, stored as a Mailer property. | optional | settable | Accessed via property array; class: hudson.tasks.Mailer$UserProperty |
Core endpoints
List all users
- Method: GET
- URL:
http://<jenkins-host>/asynchPeople/api/json - Watch out for: Returns users who have interacted with builds, not necessarily all configured users. Use /securityRealm/user/ for realm-specific lookups.
Request example
GET /asynchPeople/api/json
Authorization: Basic <base64(user:token)>
Response example
{
"_class": "jenkins.model.Jenkins$AsynchPeople",
"users": [
{"lastChange": 1700000000000,
"project": null,
"user": {"absoluteUrl": "http://jenkins/user/admin", "fullName": "admin"}}
]
}
Get user details
- Method: GET
- URL:
http://<jenkins-host>/user/<username>/api/json - Watch out for: Returns 404 if the user does not exist in the active security realm.
Request example
GET /user/jdoe/api/json
Authorization: Basic <base64(user:token)>
Response example
{
"_class": "hudson.model.User",
"absoluteUrl": "http://jenkins/user/jdoe",
"description": null,
"fullName": "John Doe",
"id": "jdoe",
"property": []
}
Create user (Jenkins own user database)
- Method: POST
- URL:
http://<jenkins-host>/securityRealm/createAccountByAdmin - Watch out for: Only works when 'Jenkins' own user database' security realm is active. Requires a valid CSRF crumb. This is a form-based endpoint, not a JSON API.
Request example
POST /securityRealm/createAccountByAdmin
Content-Type: application/x-www-form-urlencoded
Jenkins-Crumb: <crumb>
username=jdoe&password1=secret&password2=secret&fullname=John+Doe&email=jdoe@example.com
Response example
HTTP 302 redirect to /securityRealm/ on success.
Delete user
- Method: POST
- URL:
http://<jenkins-host>/securityRealm/user/<username>/doDelete - Watch out for: Requires Overall/Administer. Only available with Jenkins own user database realm. CSRF crumb mandatory.
Request example
POST /securityRealm/user/jdoe/doDelete
Jenkins-Crumb: <crumb>
Authorization: Basic <base64(admin:token)>
Response example
HTTP 302 redirect on success.
Get CSRF crumb (required for all POST requests)
- Method: GET
- URL:
http://<jenkins-host>/crumbIssuer/api/json - Watch out for: Crumbs are session-scoped. When using API tokens with Basic Auth, crumb validation may be bypassed depending on Jenkins version and configuration (>= 2.176.2 API tokens exempt from CSRF by default).
Request example
GET /crumbIssuer/api/json
Authorization: Basic <base64(user:token)>
Response example
{
"_class": "hudson.security.csrf.DefaultCrumbIssuer",
"crumb": "abc123def456",
"crumbRequestField": "Jenkins-Crumb"
}
Assign role to user (Role Strategy Plugin)
- Method: POST
- URL:
http://<jenkins-host>/role-strategy/strategy/assignRole - Watch out for: Requires Role Strategy Plugin to be installed and active as the authorization strategy. 'type' must be globalRoles, projectRoles, or slaveRoles.
Request example
POST /role-strategy/strategy/assignRole
Content-Type: application/x-www-form-urlencoded
Jenkins-Crumb: <crumb>
type=globalRoles&roleName=developer&sid=jdoe
Response example
HTTP 200 OK (empty body on success)
Get all roles (Role Strategy Plugin)
- Method: GET
- URL:
http://<jenkins-host>/role-strategy/strategy/getAllRoles - Watch out for: Returns roles and their assigned SIDs. Requires Role Strategy Plugin.
Request example
GET /role-strategy/strategy/getAllRoles?type=globalRoles
Authorization: Basic <base64(admin:token)>
Response example
{
"admin": {"sids": ["admin"]},
"developer": {"sids": ["jdoe", "jsmith"]}
}
Unassign role from user (Role Strategy Plugin)
- Method: POST
- URL:
http://<jenkins-host>/role-strategy/strategy/unassignRole - Watch out for: Does not delete the user; only removes the role assignment. Requires Role Strategy Plugin.
Request example
POST /role-strategy/strategy/unassignRole
Content-Type: application/x-www-form-urlencoded
Jenkins-Crumb: <crumb>
type=globalRoles&roleName=developer&sid=jdoe
Response example
HTTP 200 OK (empty body on success)
Rate limits, pagination, and events
Rate limits: Jenkins has no built-in API rate limiting. Rate limiting is entirely dependent on the hosting environment, reverse proxy configuration, or plugins.
Rate-limit headers: No
Retry-After header: No
Rate-limit notes: No native rate limiting. Operators may configure rate limiting via nginx/Apache reverse proxy or the 'throttle-concurrent-builds' plugin. CloudBees CI may impose additional controls.
Pagination method: none
Default page size: 0
Max page size: 0
Pagination pointer: tree
Webhooks available: No
Webhook notes: Jenkins does not provide native outbound webhooks for user management events (user creation, deletion, role changes). Jenkins does support inbound webhooks (e.g., SCM triggers) and outbound build notifications via plugins.
Alternative event strategy: Use the Audit Trail Plugin or logging to capture user management events. Poll /asynchPeople/api/json or /securityRealm/ endpoints for user state changes. For build event webhooks, use the Generic Webhook Trigger Plugin or Notification Plugin.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: N/A
- Endpoint: Not documented
Limitations:
- Jenkins has no native SCIM 2.0 support.
- User provisioning via IdP is typically handled through SAML JIT (Just-In-Time) provisioning using the SAML Plugin.
- LDAP/Active Directory realms can be used for directory-based user sync but are not SCIM.
- CloudBees CI does not add native SCIM support as of the last verified documentation.
Common scenarios
Three automation scenarios cover the majority of lifecycle operations.
First, provisioning a local user: fetch a crumb, POST to /securityRealm/createAccountByAdmin with form fields (username, password1, password2, fullname, email), confirm with GET /user/
Second, offboarding: unassign all roles via /role-strategy/strategy/unassignRole, then POST to /securityRealm/user/
type=globalRoles and ? type=projectRoles to retrieve all role-to-SID mappings, then cross-reference against /asynchPeople/api/json using the tree parameter to filter to id, fullName, and email fields.
All three scenarios require the Role Strategy plugin installed and set as the active Authorization Strategy, and all three apply only to the internal user database realm.
Provision a new local user and assign a role
- Ensure 'Jenkins own user database' is the active security realm and 'Role-based Authorization Strategy' (Role Strategy Plugin) is active.
- Fetch a CSRF crumb: GET /crumbIssuer/api/json with admin Basic Auth credentials.
- Create the user: POST /securityRealm/createAccountByAdmin with form fields username, password1, password2, fullname, email and the Jenkins-Crumb header.
- Verify user exists: GET /user/
/api/json. - Assign a global role: POST /role-strategy/strategy/assignRole with type=globalRoles, roleName=
, sid= and the Jenkins-Crumb header.
Watch out for: User creation endpoint returns an HTTP 302 redirect, not a JSON confirmation. Check the redirect target or follow up with a GET to confirm creation. If CSRF crumb is stale, the POST will return HTTP 403.
Deprovision a user (offboarding)
- Fetch a CSRF crumb: GET /crumbIssuer/api/json.
- Unassign all roles: POST /role-strategy/strategy/unassignRole for each role the user holds.
- Delete the user: POST /securityRealm/user/
/doDelete with the Jenkins-Crumb header. - Confirm deletion: GET /user/
/api/json should return HTTP 404.
Watch out for: Deletion only works with Jenkins own user database realm. For LDAP/SAML users, disable the account in the upstream directory instead. Active sessions are not immediately terminated on deletion.
Audit current user-role assignments
- Ensure Role Strategy Plugin is installed and active.
- GET /role-strategy/strategy/getAllRoles?type=globalRoles with admin credentials to retrieve all global roles and their assigned SIDs.
- GET /role-strategy/strategy/getAllRoles?type=projectRoles for project-scoped roles.
- Cross-reference SIDs against /asynchPeople/api/json to correlate with user metadata (fullName, email).
- Use the 'tree' query parameter to limit response fields: ?tree=users[user[id,fullName,property[address]]]
Watch out for: /asynchPeople/api/json may not list all users - only those with build activity. Users provisioned via SAML JIT who have never triggered a build may not appear.
Why building this yourself is a trap
The most consequential caveat is realm-coupling: every user management endpoint is conditional on the active security realm, and there is no API-level abstraction over this. Callers must detect the active realm before attempting create or delete operations, or accept silent failures and 302 redirects to error pages.
The /asynchPeople/api/json endpoint is not a user roster - it reflects build participation, so SAML JIT users who have authenticated but never triggered a build will be absent, creating gaps in any identity graph built from this source alone.
There is no native pagination; use the tree query parameter to limit payload size, but note this is a projection filter, not a cursor. Deleting a user via API does not terminate active sessions or invalidate existing API tokens immediately, meaning a deleted account can continue to authenticate until session expiry.
Jenkins has no built-in TLS enforcement on self-hosted instances, so API token security over plain HTTP is an operator responsibility, not a platform control.
Automate Jenkins 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.