Hi Community,
We are migrating from the deprecated /rest/api/3/search endpoint (Basic Auth + API token) to the new /rest/api/3/jql/search endpoint which requires OAuth 2.0 granular scopes.
Here’s what we’ve done so far:
Created an OAuth 2.0 (3LO) app in the Atlassian developer console.
Requested granular scopes:
read:jql:jira
validate:jql:jira
Completed the consent flow using the authorization URL with these scopes.
Successfully exchanged the code for an access token.
When decoding the access token, we do see:
<span>"scope": "read:jql:jira validate:jql:jira"</span>
However, when we try to call the JQL endpoint:
<span>POST <a href="https://api.atlassian.com/ex/jira/%7BcloudId%7D/rest/api/3/jql/search" rel="noopener nofollow noreferrer" target="_blank">https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3/jql/search</a> Authorization: Bearer <access_token> Content-Type: application/json { "queries": [ { "query": "project = TEST AND created >= -7d", "maxResults": 5, "fields": ["key", "summary", "status"] } ] } </span>
We still get this error:
<span>{"code":401,"message":"Unauthorized; scope does not match"}</span>
Questions:
Are read:jql:jira and validate:jql:jira the correct scopes for using the new JQL API?
Should we remove legacy scopes (like read:jira-work) completely and only use granular scopes?
Why does the token show the correct scopes but the request still fails with Unauthorized; scope does not match?
Is there any migration guidance specific to JQL and granular scopes beyond the changelog note (CHANGE-2046)?