JIRA Cloud REST API (OAuth 2.0) Error 403 on POST Requests



I am trying to connect my React app to the Jira Cloud API and can’t seem to get past a 403 error.

Response Error
:status: 403
Content-Type: text/html;charset=UTF-8
Access-Control-Allow-Origin: http://localhost:3000
Content-Encoding: gzip
X-XSS-Protection: 1; mode=block
Timing-Allow-Origin: *
Cache-Control: no-cache, no-store, no-transform
Date: Mon, 17 Dec 2018 21:42:01 GMT
Access-Control-Allow-Credentials: true
X-Content-Type-Options: nosniff
Vary: Origin, Accept-Encoding
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=315360000; includeSubDomains; preload

My code currently does a Auth dance using OAuth 2.0 and returns the token and cloudid. I can use this to GET issues, however POST request (like creating an issue) return with 403. I have found here that this error is returned if the user does not have the necessary permission to access the resource or run the method.

I have ensured the user has the correct scope ([write: jira-work, read: jira-work]) and verified this is reflected in the user account (in their account > connect apps tab).

My app is not linked (via ApplicationLink) or installed (via Apps, Manage Apps), is this necessary to perform POST requests?

Here is a sample of my code:

fetch(`https://api.atlassian.com/ex/jira/${jira.cloudid}/rest/api/2/issue/`, {
        method: "POST",
        headers: {
            "Content-Type": 'application/json',
            "Authorization": `Bearer ${jira.token}`
        body: JSON.stringify(data)

Neither api version 2 or 3 are working for this POST request. I have explored using Basic Auth however this fails due to CORS errors.

I have verified that the POST request does work in POSTMAN (using the cloudid and token).

Can anyone confirm if this API allows for client side POST requests?

Any help would be great!


Hi @charlesklewis,

could you check and post the body of the response? It might have a hint.

Also, the code sample you posted has the body defined outside of the options object.




Hello @sreuter, thanks for the reply. Not sure what you mean by the body is outside of the options, the code follows the standard POST syntax for Fetch. I have updated the format a little to make this easier to see.

I have posted the response error (body) in my original post but can’t seem to see the issue (I removed some of the sensitive information like username, token etc). The only potential issue I can see is has an X-Frame-Options: SAMEORIGIN. This could imply that I have to post using same origin, hence the 403 error.


Hi Charles,

apologies, I only saw the headers but not a response body above.

This should log the error from the body if there’s any:

    method: 'POST',
    headers: new Headers({
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
      'X-Atlassian-Token': 'no-check'
    body: JSON.stringify({test: 'test'})
).then((body) => {
  return body.text();
}).then((bodyText) => {
}).catch((err) => {console.log(err)});

By trying the same thing you mentioned I think I found what the problem is. Your request likely fails with a ‘XSRF check failed’ in the browser.

I’ve already talked to one of our security engineers and we quickly dived into the implementation code to confirm why this not working and what would need to be changed on our side. We’ve also already opened a engineering ticket to get this addressed. This will likely take a few weeks to get addressed, but I’ll keep you posted if I hear any updates!



Oauth 2 3L wont work with local apps - CORS issue for authenticated apps

Hello @sreuter,

Yes you are correct, the two errors I receive are:

  • XSRF check failed
  • Failed to load resource: the server responded with a status of 403 ()

That would be great, thank you! If there is any testing you would like me to do feel welcome to let me know.


Hello @sreuter,

Checking in to see if there are any updates on this.