The Atlassian Community Forums are currently in read-only mode. We will be relaunching on a new platform on September 22 (read more here). We apologize for the extended downtime. For concerns or questions, please email communitymanagers@atlassian.com. See you on the other side, on the new Atlassian Community Forums! :)

×

Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Difference between OAuth2 token and API key?

KC Wong
Contributor
August 28, 2026

I have a service account. 

I'm trying to use REST API to read/update issues using: 
https://api.atlassian.com/ex/jira/<Cloud ID>/rest/api/2/issue/<IssueKey>
or 
https://<MyDomain>.atlassian.net/rest/api/2/issue/<IssueKey>

If I create an API key, give it scopes read:jira-work and write:jira-work, it works. 

But if I create an OAuth2 token, give it the same scopes, it doesn't work saying I do not have permission to the issue. 

Given it's the same service account, it cannot be anything related to permissions. What additional scopes do the OAuth2 token need and why? 

2 answers

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

0 votes
Sami Shaik
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Champions.
August 31, 2026

Hi @KC Wong , @Arkadiusz Wroblewski covered the URL and header half correctly, so I will take the part you are actually asking about: why two credentials with the same two scopes behave differently. Short version: they are not being evaluated against the same scope list.

The three layers first, because the failing one is usually not the one people suspect. A service account can only perform an action if all three line up: product access (the account has Jira), permission access (it holds the role or permission in the space), and credential scope (the token is allowed to do that action). Your API token and OAuth credential share the first two layers, since they belong to the same service account. They differ only in the third, and that is where your error is.

Why the third layer differs: an OAuth 2.0 credential on a service account is checked per endpoint against the granular scopes listed for that endpoint in the REST documentation, and the scope catalogue available to the OAuth credential is not the same as the classic catalogue. Atlassian has confirmed this in a tracked bug for the JSM side, where classic scopes are not even offered during credential creation and each API call carries its own granular requirements: https://jira.atlassian.com/browse/JSDCLOUD-17697. The practical consequence: an endpoint that "works" under read:jira-work on one path can demand two or three additional granular scopes on the OAuth path, most often a user scope (any response containing user objects, which includes search and work item responses) and product-specific granular scopes. The clue you already found, that a broader-scope token works while the two-scope token does not, is exactly this: the endpoint needs a scope you have not granted, and the OAuth path is strict about it.

Diagnose it in two calls rather than guessing:

  1. Ask the token what it actually holds: GET https://api.atlassian.com/oauth/token/accessible-resources with your Bearer token returns the site and the scopes attached to that token. Documented here: https://developer.atlassian.com/cloud/jira/software/oauth-2-3lo-apps/
  2. Open the REST reference page for the exact endpoint you are calling and read its OAuth scopes required block. It lists classic and granular scopes separately. Add every granular scope listed for that endpoint to the credential (you cannot edit scopes on an existing credential, so create a new one: https://support.atlassian.com/user-management/docs/create-oauth-2-0-credential-for-service-accounts/), then retest.

Two boundaries worth knowing. If your endpoint is under /rest/servicedeskapi/, you are inside the JSDCLOUD-17697 bug and the OAuth credential may simply not be able to satisfy it yet; the scoped API token is the working path until that is fixed. And for either credential type, the gateway URL form matters: scoped tokens only work against https://api.atlassian.com/ex/jira/<cloudId>/..., never the site URL, per this KB: https://support.atlassian.com/atlassian-cloud/kb/401-unauthorized-error-when-service-account-accesses-jira-or-confluence-api/

If you share which endpoint returns the error, I can point at the specific scopes it is missing.

0 votes
Arkadiusz Wroblewski
Community Champion
August 28, 2026

Hello @KC Wong 

For an OAuth 2.0 credential created for an Atlassian service account, the documented request is through the Atlassian API gateway:

https://api.atlassian.com/ex/jira/{cloudId}/rest/api/2/issue/{issueKey}: Authorization: Bearer <ACCESS_TOKEN>

Here some official resources https://support.atlassian.com/user-management/docs/create-oauth-2-0-credential-for-service-accounts/ 

https://support.atlassian.com/user-management/docs/manage-api-tokens-for-service-accounts/ 

Best,

Arek 🤠 

KC Wong
Contributor
August 30, 2026

I KNOW. I know the difference between Authorization = Basic vs Bearer.

I should've said it more clearly.  

I have another OAuth2 token with a lot more scopes. That one can read/update issue data. 

If I create a new OAuth2 token with just read:jira-work and write:jira-work, it does not work. 

DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
PREMIUM
TAGS
AUG Leaders

Atlassian Community Events