A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Jira API is how an app or AI agent works with a Jira site: reading and creating issues, moving them through their workflow with transitions, searching with the Jira Query Language, and posting comments. Access is granted through an OAuth token and a set of scopes that decide which areas a call can read or write, and a token never reaches past the permissions of the person who authorized it. Jira can also push events, like an issue being created or updated, to a registered webhook URL.
How an app or AI agent connects to Jira determines what it can reach. There is a route for making calls, a route for receiving events, a hosted server that exposes Jira to agents, and two app frameworks, and each is governed by the token or grant behind it and the permissions it carries.
The Jira Cloud platform REST API is reached per site through a base address that includes the site's cloud ID, found by calling the accessible-resources endpoint after authentication. A call authenticates with an OAuth 2.0 (3LO) access token, or with an email and API token over basic auth for a script acting as one user. Version 3 is the current API.
Atlassian's official Rovo MCP server lets an AI agent reach Jira through the Model Context Protocol. The remote server is at https://mcp.atlassian.com/v1/mcp and reached general availability on 4 February 2026. It uses OAuth 2.1, so every action runs within the signed-in user's existing Jira permissions, and it can search and read issues and create or update work items. It also covers Confluence, Bitbucket, and Jira Service Management.
Jira posts an event payload to a registered URL when a chosen event happens, like an issue being created or a comment added. A dynamic webhook is registered through the REST API and filtered by a JQL query, and expires 30 days after it is created or refreshed. Connect and Forge apps can instead declare webhooks in their app definition.
Forge is Atlassian's app platform, where the app runs inside Atlassian's own infrastructure rather than on a vendor's servers, so customer data does not leave Atlassian. Since 17 September 2025 only Forge apps can be submitted to the Atlassian Marketplace. A Forge app declares the scopes it needs and can call the REST API and receive webhooks.
Connect is Atlassian's older app framework, where the app is hosted on the vendor's own infrastructure and Jira sends data out to it. It is being superseded by Forge for new Marketplace apps, but remains in use. A Connect app can call the REST API and declare webhook modules.
Three-legged OAuth lets an external app act on a user's behalf. The user is sent to auth.atlassian.com to consent to a set of scopes, the app exchanges the returned code for an access token, and adding offline_access yields a refresh token to keep access alive. Each call goes to the site's base address, found from the access token's accessible resources.
An email address plus an API token authenticates a request over HTTP basic auth, acting as that one user with that user's permissions. It suits a script or a direct call rather than an app many people authorize, since there is no consent flow and no per-scope grant.
A Forge app authenticates as itself or as the user, with the scopes declared in its manifest, and runs inside Atlassian's infrastructure. It is the recommended route for a Marketplace app, since only Forge apps can be submitted from 17 September 2025.
The Jira API is split into areas an agent can act on, like issues, transitions, projects, comments, worklogs, and users. Each area has its own methods and its own permissions, and writes in some areas change project configuration rather than a single issue.
Read, create, edit, and delete issues, and read an issue's change history and edit metadata.
List the transitions available on an issue, move an issue through its workflow, and set an assignee.
Search for issues with the Jira Query Language, by URL parameter or in a request body.
List the comments on an issue, add a comment, and update one.
Search projects, read a single project, read its statuses, and create a project.
Read the current user, read a user by account ID, and search for users.
List the work logged against an issue and add a worklog entry.
Add a file to an issue and read an attachment's metadata.
List the fields defined on the site and register a dynamic webhook to receive events.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
IssuesRead, create, edit, and delete issues, and read an issue's change history and edit metadata.6 | ||||||
| GET | /rest/api/3/issue/{issueIdOrKey} | Get a single issue by its ID or key. | read | read:jira-work | Current | |
Granular OAuth scope: read:issue:jira (plus auxiliary read scopes for expanded fields like the changelog or vote count). Acts onissue Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/api/3/issue | Create an issue, or a subtask, in a project. | write | write:jira-work | Current | |
Granular OAuth scope: write:issue:jira. Rich text fields, like the description, are sent as the Atlassian Document Format in version 3. Acts onissue Permission (capability) write:jira-workVersionAvailable since the API’s base version Webhook event jira-issue-createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /rest/api/3/issue/{issueIdOrKey} | Edit an issue's fields. | write | write:jira-work | Current | |
Granular OAuth scope: write:issue:jira. Acts onissue Permission (capability) write:jira-workVersionAvailable since the API’s base version Webhook event jira-issue-updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /rest/api/3/issue/{issueIdOrKey} | Delete an issue, and optionally its subtasks. | write | write:jira-work | Current | |
Granular OAuth scope: delete:issue:jira. The classic write:jira-work scope covers deletion too, so a classic token cannot delete without also being able to create and edit. Acts onissue Permission (capability) write:jira-workVersionAvailable since the API’s base version Webhook event jira-issue-deletedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/api/3/issue/{issueIdOrKey}/changelog | Get an issue's change history, paginated. | read | read:jira-work | Current | |
Granular OAuth scope: read:issue.changelog:jira. Acts onissue Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/api/3/issue/{issueIdOrKey}/editmeta | Get the metadata describing which fields can be edited on an issue. | read | read:jira-work | Current | |
Granular OAuth scope: read:issue-meta:jira. Useful before an edit, to learn which fields the user may change. Acts onissue Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Transitions & assignmentList the transitions available on an issue, move an issue through its workflow, and set an assignee.3 | ||||||
| GET | /rest/api/3/issue/{issueIdOrKey}/transitions | List the workflow transitions available on an issue from its current status. | read | read:jira-work | Current | |
Granular OAuth scope: read:issue.transition:jira. The available transitions depend on the issue's workflow and the user's permissions. Acts ontransition Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/api/3/issue/{issueIdOrKey}/transitions | Move an issue through a workflow transition, optionally setting fields at the same time. | write | write:jira-work | Current | |
Granular OAuth scope: write:issue:jira. The transition ID comes from the Get transitions method, since transitions are workflow-specific. Acts ontransition Permission (capability) write:jira-workVersionAvailable since the API’s base version Webhook event jira-issue-updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /rest/api/3/issue/{issueIdOrKey}/assignee | Assign an issue to a user, identified by account ID. | write | write:jira-work | Current | |
Granular OAuth scope: write:issue:jira. The user is set by accountId, since usernames are no longer accepted. Acts onissue Permission (capability) write:jira-workVersionAvailable since the API’s base version Webhook event jira-issue-updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Search (JQL)Search for issues with the Jira Query Language, by URL parameter or in a request body.2 | ||||||
| GET | /rest/api/3/search/jql | Search for issues with a Jira Query Language query, passed as a URL parameter. | read | read:jira-work | Current | |
Granular OAuth scope: read:issue-details:jira. This is the current enhanced search; it replaced the older /rest/api/3/search method, which stopped responding at the end of October 2025. It pages by a continuation token rather than a result total. Acts onsearch result Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/api/3/search/jql | Search for issues with a Jira Query Language query, passed in a request body. | read | read:jira-work | Current | |
Granular OAuth scope: read:issue-details:jira. The body form suits long queries and explicit field lists. Acts onsearch result Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
CommentsList the comments on an issue, add a comment, and update one.3 | ||||||
| GET | /rest/api/3/issue/{issueIdOrKey}/comment | List the comments on an issue, paginated. | read | read:jira-work | Current | |
Granular OAuth scope: read:comment:jira. Acts oncomment Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/api/3/issue/{issueIdOrKey}/comment | Add a comment to an issue. | write | write:jira-work | Current | |
Granular OAuth scope: write:comment:jira. The comment body is sent as the Atlassian Document Format in version 3. Acts oncomment Permission (capability) write:jira-workVersionAvailable since the API’s base version Webhook event comment-createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PUT | /rest/api/3/issue/{issueIdOrKey}/comment/{id} | Update a comment on an issue. | write | write:jira-work | Current | |
Granular OAuth scope: write:comment:jira. Acts oncomment Permission (capability) write:jira-workVersionAvailable since the API’s base version Webhook event comment-updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ProjectsSearch projects, read a single project, read its statuses, and create a project.4 | ||||||
| GET | /rest/api/3/project/search | Get a paginated list of projects visible to the user. | read | read:jira-work | Current | |
Granular OAuth scope: read:project:jira (plus auxiliary read scopes for expanded project detail). Acts onproject Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/api/3/project/{projectIdOrKey} | Get a single project by its ID or key. | read | read:jira-work | Current | |
Granular OAuth scope: read:project:jira. Acts onproject Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/api/3/project/{projectIdOrKey}/statuses | Get the valid statuses for each issue type in a project. | read | read:jira-work | Current | |
Granular OAuth scope: read:issue-status:jira. Useful to learn the statuses an issue can hold before transitioning it. Acts onproject Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/api/3/project | Create a project. | write | manage:jira-configuration | Current | |
Granular OAuth scope: write:project:jira. The user must also hold the Administer Jira permission, since a scope never grants more than the user's own permissions. Acts onproject Permission (capability) manage:jira-configurationVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
UsersRead the current user, read a user by account ID, and search for users.3 | ||||||
| GET | /rest/api/3/myself | Get the profile of the currently authenticated user. | read | read:jira-user | Current | |
Granular OAuth scope: read:user:jira. Returns the caller's name, email address, and avatar. Acts onuser Permission (capability) read:jira-userVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/api/3/user | Get a user by account ID. | read | read:jira-user | Current | |
Granular OAuth scope: read:user:jira. The user is identified by accountId; the older username and key parameters are no longer available. Acts onuser Permission (capability) read:jira-userVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/api/3/user/search | Find users matching a search string, by display name or email. | read | read:jira-user | Current | |
Granular OAuth scope: read:user:jira. Returns people's names, email addresses, and avatars. Acts onuser Permission (capability) read:jira-userVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
WorklogsList the work logged against an issue and add a worklog entry.2 | ||||||
| GET | /rest/api/3/issue/{issueIdOrKey}/worklog | List the worklogs recorded against an issue, paginated. | read | read:jira-work | Current | |
Granular OAuth scope: read:issue-worklog:jira. Acts onworklog Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/api/3/issue/{issueIdOrKey}/worklog | Add a worklog entry to an issue, recording time spent. | write | write:jira-work | Current | |
Granular OAuth scope: write:issue-worklog:jira. Adding a worklog can adjust the issue's remaining estimate. Acts onworklog Permission (capability) write:jira-workVersionAvailable since the API’s base version Webhook event worklog-createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
AttachmentsAdd a file to an issue and read an attachment's metadata.2 | ||||||
| POST | /rest/api/3/issue/{issueIdOrKey}/attachments | Attach one or more files to an issue. | write | write:jira-work | Current | |
Granular OAuth scope: write:attachment:jira. The request must send the file as multipart form data and carry an X-Atlassian-Token: no-check header, or it is blocked. Acts onattachment Permission (capability) write:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /rest/api/3/attachment/{id} | Get an attachment's metadata, such as its filename, size, and author. | read | read:jira-work | Current | |
Granular OAuth scope: read:attachment:jira. This returns metadata, not the file content. Acts onattachment Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Fields & webhooksList the fields defined on the site and register a dynamic webhook to receive events.2 | ||||||
| GET | /rest/api/3/field | List the fields, both system and custom, defined on the site. | read | read:jira-work | Current | |
Granular OAuth scope: read:field:jira. The field IDs returned here are the keys used when reading or writing an issue's fields. Acts onfield Permission (capability) read:jira-workVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /rest/api/3/webhook | Register one or more dynamic webhooks, each filtered by a JQL query. | write | manage:jira-webhook | Current | |
Granular OAuth scope: write:webhook:jira. Only Connect and OAuth 2.0 apps can register dynamic webhooks, and each expires 30 days after it is created or refreshed. Acts onwebhook Permission (capability) manage:jira-webhookVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Jira can notify an app or AI agent when something happens in a site, like an issue being created or a comment added, instead of the app repeatedly asking. Jira posts the event payload to a webhook URL registered for the chosen events.
| Event | What it signals | Triggered by |
|---|---|---|
jira:issue_created | Fires when an issue is created. | /rest/api/3/issue |
jira:issue_updated | Fires when an issue is edited, transitioned, or reassigned. | /rest/api/3/issue/{issueIdOrKey}/rest/api/3/issue/{issueIdOrKey}/transitions/rest/api/3/issue/{issueIdOrKey}/assignee |
jira:issue_deleted | Fires when an issue is deleted. | /rest/api/3/issue/{issueIdOrKey} |
comment_created | Fires when a comment is added to an issue. | /rest/api/3/issue/{issueIdOrKey}/comment |
comment_updated | Fires when a comment is edited. | /rest/api/3/issue/{issueIdOrKey}/comment/{id} |
comment_deleted | Fires when a comment is removed from an issue. | In-app only |
worklog_created | Fires when time is logged against an issue. | /rest/api/3/issue/{issueIdOrKey}/worklog |
worklog_updated | Fires when a worklog entry is changed. | In-app only |
worklog_deleted | Fires when a worklog entry is removed. | In-app only |
Jira limits how fast and how much an app or AI agent can call, through a points-based cost budget rather than a fixed request count, with separate per-second and per-issue write limits on top.
Jira Cloud does not meter by a fixed request count. It uses a points-based cost budget, where each call spends points according to its complexity and the data it returns, with separate per-second burst limits and a per-issue write limit layered on top. Going over any of these returns HTTP 429, with a Retry-After header giving the seconds to wait, a RateLimit-Reason header naming which limit was hit (such as a tenant points quota, a burst limit, or the per-issue write limit), and X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers reporting the state. Atlassian states the exact thresholds are subject to change and does not commit to fixed published numbers, so an integration should respect the headers and back off rather than assume a constant ceiling.
List methods are paginated. Most use startAt and maxResults offset parameters and report the total available, with maxResults commonly capped around 50 to 100 depending on the method. The current JQL search method at /rest/api/3/search/jql pages differently: it returns a nextPageToken to fetch the following page and no longer reports a result total, so an integration follows the token until it is absent rather than counting pages.
Responses are JSON. Rich text fields, like an issue description or a comment body, are represented as the Atlassian Document Format, a JSON structure, in version 3, where version 2 uses wiki markup strings. Attachment uploads are sent as multipart form data and are subject to the site's configured maximum attachment size.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | Bad Request | The request was malformed, or a field or parameter was invalid. The body carries an errorMessages array of general messages and an errors object mapping a field name to its message. | Read the errorMessages and errors in the body, correct the named field, and resend. |
| 401 | Unauthorized | Authentication is missing or invalid, so the caller is not signed in. | Send a valid access token or API token, refreshing it first if it has expired. |
| 403 | Forbidden | The caller is authenticated but lacks the permission or scope the request needs. | Grant the missing scope, or confirm the user holds the required Jira permission, then retry. |
| 404 | Not Found | The issue, project, or other object does not exist, or the user is not permitted to see it. Jira returns 404 rather than 403 in some cases so it does not confirm a hidden object exists. | Confirm the ID or key is correct and the user has access to the object. |
| 429 | Too Many Requests | A rate limit was exceeded, either the points-based cost budget, the per-second burst limit, or the per-issue write limit. A RateLimit-Reason header names which one was hit. | Wait the number of seconds in the Retry-After header before retrying, and back off on repeated 429s. |
Jira keeps version 3 as the latest REST API, offering the same operations as version 2 but representing rich text fields, like a description or a comment body, as the Atlassian Document Format instead of wiki markup.
Version 3 of the Jira Cloud platform REST API is the latest version. It offers the same collection of operations as version 2, but represents rich text fields, like an issue description or a comment body, as the Atlassian Document Format, a JSON structure, rather than wiki markup. There is no dated version scheme; both version 2 and version 3 are live, and version 3 is the recommended one to build on. The entries below are notable dated changes to the platform that affect agents building on it.
Atlassian announced resource-restricted tokens for OAuth 2.0 (3LO) apps, alongside a Partner Security Incident Response Program, narrowing what an access token can reach.
The older issue-search methods at /rest/api/3/search, by GET and POST, were progressively shut down through the second half of 2025 and stopped responding at the end of October 2025, replaced by the enhanced search at /rest/api/3/search/jql. The new method pages by a continuation token and no longer returns a result total, which is a behavioral change for anything that paginated on the total.
From 17 September 2025, only Forge apps can be submitted to the Atlassian Marketplace, and new extensibility features ship Forge-first. Connect apps remain in use but are being superseded.
Version 2 and version 3 are both live; version 3 is the one to build on.
Jira platform changelog ↗Bollard AI sits between a team's AI agents and Jira. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.