Summary and recommendation
Jira Cloud exposes a REST API v3 at `https://your-domain.atlassian.net/rest/api/3` supporting OAuth 2.0 (3LO) and API Token (Basic Auth). The `accountId` field is the only supported user identifier following Atlassian's 2019 GDPR-related API changes - `username` and `userKey` are fully removed.
User profile fields (email, displayName, timezone) are managed at the Atlassian Account level, not the Jira level, so updates to those fields require the Atlassian Account API or the admin console, not the Jira REST API.
For teams managing Jira alongside a broader SaaS portfolio, Stitchflow's MCP server with ~100 deep IT/identity integrations provides a unified provisioning layer that abstracts these per-app API differences.
API quick reference
| Has user API | Yes |
| Auth method | OAuth 2.0 (3LO) or API Token (Basic Auth) |
| Base URL | Official docs |
| SCIM available | Yes |
| SCIM plan required | Atlassian Guard (formerly Atlassian Access) subscription required; Guard Standard plan includes SCIM. Jira Enterprise plan includes Guard Standard. |
Authentication
Auth method: OAuth 2.0 (3LO) or API Token (Basic Auth)
Setup steps
- For OAuth 2.0 (3LO): Register an app at https://developer.atlassian.com/console/myapps/, enable the Jira API, configure redirect URIs, and request the required scopes.
- Direct users through the Atlassian OAuth 2.0 authorization URL to obtain an authorization code.
- Exchange the authorization code for an access token via POST https://auth.atlassian.com/oauth/token.
- Use the access token as a Bearer token in the Authorization header for all API requests.
- For API Token (Basic Auth): Generate a token at https://id.atlassian.com/manage-profile/security/api-tokens, then use Base64-encoded 'email:token' as Basic Auth credentials.
Required scopes
| Scope | Description | Required for |
|---|---|---|
| read:jira-user | Read user profile information | GET /user, GET /users/search, GET /user/bulk |
| write:jira-work | Create and update Jira content including user-related operations | POST /user (create user) |
| manage:jira-configuration | Manage Jira configuration including user management | DELETE /user, PUT /user/columns |
| read:account | Read Atlassian account profile data | Accessing account-level user data via Atlassian Account API |
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| accountId | string | Unique Atlassian account ID (AAID) | system-assigned | immutable | Primary identifier; replaces deprecated 'key' and 'name' fields |
| accountType | string | Type of account: atlassian, app, or customer | system-assigned | read-only | Only 'atlassian' accounts are full Jira users |
| emailAddress | string | User's email address | required | via Atlassian Account API | May be hidden based on user privacy settings |
| displayName | string | User's display name | optional | via Atlassian Account API | May be hidden based on privacy settings |
| active | boolean | Whether the user account is active | system-assigned (true) | read-only via Jira API; managed via admin console or SCIM | Deactivation is done via Atlassian admin or SCIM, not Jira REST API directly |
| avatarUrls | object | Map of avatar image URLs (16x16, 24x24, 32x32, 48x48) | system-assigned | read-only | |
| timeZone | string | User's time zone (IANA format) | optional | via Atlassian Account API | |
| locale | string | User's locale (e.g., en_US) | optional | via Atlassian Account API | |
| groups | object | Groups the user belongs to (paginated list) | not set here | via group membership endpoints | Returned only when expand=groups is specified |
| applicationRoles | object | Application roles assigned to the user | not set here | via admin console | Returned only when expand=applicationRoles is specified |
| self | string (URL) | URL of the user resource | system-assigned | read-only |
Core endpoints
Get user by accountId
- Method: GET
- URL:
https://your-domain.atlassian.net/rest/api/3/user?accountId={accountId} - Watch out for: emailAddress may be null if the user has set their profile to private.
Request example
GET /rest/api/3/user?accountId=5b10a2844c20165700ede21g
Authorization: Bearer {token}
Response example
{
"accountId": "5b10a2844c20165700ede21g",
"emailAddress": "user@example.com",
"displayName": "Jane Doe",
"active": true,
"timeZone": "America/New_York",
"accountType": "atlassian"
}
Search users
- Method: GET
- URL:
https://your-domain.atlassian.net/rest/api/3/user/search?query={query}&startAt=0&maxResults=50 - Watch out for: Returns only users visible to the authenticated user. Use /rest/api/3/users/search for all users (requires admin scope).
Request example
GET /rest/api/3/user/search?query=jane&startAt=0&maxResults=50
Authorization: Bearer {token}
Response example
[
{
"accountId": "5b10a2844c20165700ede21g",
"displayName": "Jane Doe",
"active": true
}
]
Get all users (bulk)
- Method: GET
- URL:
https://your-domain.atlassian.net/rest/api/3/users/search?startAt=0&maxResults=50 - Watch out for: Requires site-admin permissions. Returns all user types including app and customer accounts.
Request example
GET /rest/api/3/users/search?startAt=0&maxResults=50
Authorization: Bearer {token}
Response example
[
{
"accountId": "5b10a2844c20165700ede21g",
"displayName": "Jane Doe",
"active": true,
"accountType": "atlassian"
}
]
Create user
- Method: POST
- URL:
https://your-domain.atlassian.net/rest/api/3/user - Watch out for: This endpoint creates a Jira-managed user and sends an invitation email. For SSO/SCIM-managed orgs, user creation should go through SCIM or the IdP instead.
Request example
POST /rest/api/3/user
Authorization: Bearer {token}
Content-Type: application/json
{
"emailAddress": "newuser@example.com",
"displayName": "New User",
"products": ["jira-software"]
}
Response example
{
"accountId": "5b10ac8d82e05b22cc7d4ef5",
"emailAddress": "newuser@example.com",
"displayName": "New User",
"active": true
}
Delete user
- Method: DELETE
- URL:
https://your-domain.atlassian.net/rest/api/3/user?accountId={accountId} - Watch out for: Deletes the user from the Jira site but does not delete the Atlassian account. Requires site-admin. Cannot delete users managed by an external IdP via SCIM.
Request example
DELETE /rest/api/3/user?accountId=5b10ac8d82e05b22cc7d4ef5
Authorization: Bearer {token}
Response example
HTTP 204 No Content
Get user groups
- Method: GET
- URL:
https://your-domain.atlassian.net/rest/api/3/user/groups?accountId={accountId} - Watch out for: Returns groups for the specified user. Requires read:jira-user scope.
Request example
GET /rest/api/3/user/groups?accountId=5b10a2844c20165700ede21g
Authorization: Bearer {token}
Response example
[
{
"name": "jira-software-users",
"groupId": "276f955c-63d7-42c8-9520-92d01dca0625"
}
]
Add user to group
- Method: POST
- URL:
https://your-domain.atlassian.net/rest/api/3/group/user?groupId={groupId} - Watch out for: Use groupId (not group name) as the parameter; group names are deprecated as identifiers.
Request example
POST /rest/api/3/group/user?groupId=276f955c-63d7-42c8-9520-92d01dca0625
Authorization: Bearer {token}
Content-Type: application/json
{
"accountId": "5b10a2844c20165700ede21g"
}
Response example
{
"groupId": "276f955c-63d7-42c8-9520-92d01dca0625",
"name": "jira-software-users"
}
Remove user from group
- Method: DELETE
- URL:
https://your-domain.atlassian.net/rest/api/3/group/user?groupId={groupId}&accountId={accountId} - Watch out for: Removing a user from all groups does not deactivate the account; deactivation must be done via admin console or SCIM.
Request example
DELETE /rest/api/3/group/user?groupId=276f955c-63d7-42c8-9520-92d01dca0625&accountId=5b10a2844c20165700ede21g
Authorization: Bearer {token}
Response example
HTTP 200 OK
{
"groupId": "276f955c-63d7-42c8-9520-92d01dca0625",
"name": "jira-software-users"
}
Rate limits, pagination, and events
- Rate limits: Atlassian Jira Cloud enforces rate limits per user token and per app. Limits are not publicly documented with exact numbers; they are adaptive and based on usage patterns. Exceeding limits returns HTTP 429.
- Rate-limit headers: Yes
- Retry-After header: Yes
- Rate-limit notes: When rate limited, the API returns HTTP 429 with a Retry-After header indicating seconds to wait. Atlassian recommends exponential backoff. Exact per-minute limits are not published and vary by endpoint and tenant.
- Pagination method: offset
- Default page size: 50
- Max page size: 1000
- Pagination pointer: startAt / maxResults
| Plan | Limit | Concurrent |
|---|---|---|
| All Cloud plans | Not publicly specified; adaptive rate limiting applies | 0 |
- Webhooks available: Yes
- Webhook notes: Jira Cloud supports webhooks for project and issue events. Native user lifecycle webhooks (user created, deactivated) are not available via the Jira REST API webhooks system. User events can be observed via Atlassian Guard audit logs or SCIM provisioning callbacks from the IdP.
- Alternative event strategy: Use Atlassian Guard audit log API or IdP-side SCIM provisioning events for user lifecycle notifications.
- Webhook events: jira:issue_created, jira:issue_updated, jira:issue_deleted, project_created, project_updated, project_deleted, user_created (via Atlassian Guard audit log, not Jira webhook)
SCIM API status
SCIM available: Yes
SCIM version: 2.0
Plan required: Atlassian Guard (formerly Atlassian Access) subscription required; Guard Standard plan includes SCIM. Jira Enterprise plan includes Guard Standard.
Endpoint: https://api.atlassian.com/scim/directory/{directoryId}
Supported operations: GET /Users – list users, GET /Users/{id} – get user, POST /Users – create user, PUT /Users/{id} – replace user, PATCH /Users/{id} – update user (activate/deactivate), DELETE /Users/{id} – delete user, GET /Groups – list groups, GET /Groups/{id} – get group, POST /Groups – create group, PUT /Groups/{id} – replace group, PATCH /Groups/{id} – update group members, DELETE /Groups/{id} – delete group
Limitations:
- Requires Atlassian Guard subscription (paid add-on or included in Enterprise plan).
- SSO must be configured before SCIM provisioning can be enabled.
- SCIM tokens are generated per directory in the Atlassian admin console.
- Only managed accounts (verified domain) can be provisioned via SCIM.
- SCIM deactivation sets the user to inactive but does not delete the Atlassian account.
- Supported IdPs with pre-built connectors: Okta, Microsoft Entra ID (Azure AD), Google Workspace, OneLogin, Ping Identity.
Common scenarios
Three scenarios cover the majority of programmatic user management needs. For provisioning, SCIM 2.
0 via Atlassian Guard is the correct path for SSO-managed orgs - the POST /Users endpoint on the SCIM base URL (https://api.atlassian.com/scim/directory/{directoryId}) handles account creation.
the Jira REST API POST /user endpoint creates Jira-managed users and triggers invitation emails, making it unsuitable for IdP-managed environments. For offboarding, the Jira REST API cannot deactivate accounts - deactivation must go through the admin console or a SCIM PATCH /Users/{id} with active=false.
DELETE /user removes site access but is not equivalent to account deactivation and cannot be used on SCIM-managed users.
For auditing, GET /rest/api/3/users/search with offset pagination (startAt / maxResults, max 1000 per page) returns all user types including app and customer accounts; filter client-side for accountType=atlassian and active=true.
Note that emailAddress may return null even with admin credentials due to user privacy settings - the admin console CSV export is the only reliable source of complete email data.
Provision a new employee via SCIM
- Ensure Atlassian Guard is active and the user's email domain is verified in admin.atlassian.com.
- Configure the IdP (e.g., Okta) SCIM connector with the directory SCIM URL (https://api.atlassian.com/scim/directory/{directoryId}) and a SCIM API token generated in the Atlassian admin console.
- Assign the user to the Jira application in the IdP; the IdP sends POST /Users to the SCIM endpoint.
- Atlassian creates the managed account and grants access to the configured Jira products.
- Verify the user appears in admin.atlassian.com > Directory > Users with 'Active' status.
Watch out for: The user must have an email on a verified domain. Unverified domains cannot be provisioned via SCIM.
Offboard a user (deactivate and remove from groups)
- Via SCIM: Unassign the user from the Jira app in the IdP; the IdP sends PATCH /Users/{id} with active=false to deactivate.
- Alternatively, via Atlassian admin console: navigate to admin.atlassian.com > Directory > Users, find the user, and select 'Deactivate account'.
- To remove from Jira groups via REST API: GET /rest/api/3/user/groups?accountId={accountId} to list groups, then DELETE /rest/api/3/group/user for each group.
- Verify the user's active status via GET /rest/api/3/user?accountId={accountId} returns active=false.
Watch out for: Deactivation via SCIM or admin console does not delete the Atlassian account or its data. The Jira REST API DELETE /user removes site access but is not the same as account deactivation.
Bulk-list all active users for an audit
- Authenticate with an API token (Basic Auth) or OAuth 2.0 token for a site-admin account.
- Call GET /rest/api/3/users/search?startAt=0&maxResults=1000 to retrieve the first page of users.
- Check if the response array length equals maxResults; if so, increment startAt by maxResults and repeat.
- Filter results client-side for accountType='atlassian' and active=true.
- For email addresses, note that privacy settings may hide emailAddress; use the Atlassian admin console export for complete data.
Watch out for: The /users/search endpoint requires site-admin permissions. emailAddress may be null for privacy-restricted accounts even with admin credentials via the REST API; the admin console CSV export provides full data.
Why building this yourself is a trap
Several API behaviors create non-obvious failure modes. Rate limits are adaptive and not publicly documented with fixed numbers; the API returns HTTP 429 with a Retry-After header, and Atlassian recommends exponential backoff - build this in from the start rather than treating it as an edge case.
OAuth 2.0 (3LO) tokens are scoped to the authorizing user, meaning admin operations require the authorizing user to hold site-admin rights; API tokens (Basic Auth) inherit all permissions of the generating user and do not support granular scopes.
Native Jira webhooks do not emit user lifecycle events (created, deactivated) - user events must be observed via the Atlassian Guard audit log API or IdP-side SCIM provisioning callbacks.
Finally, the MCP server with ~100 deep IT/identity integrations is the recommended abstraction for teams that need consistent user lifecycle handling across Jira and adjacent tools without re-implementing these caveats per integration.
Automate Atlassian Jira 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.