Unauthorized when handling a post from a Confluence webhook

I have a Confluence webhook setup responding to a confluence page being looked to. My app handles the callback like this:

app.post('/response', addon.authenticate(), function(req, res) {

    console.log("CONFLUENCE GET REQUEST: \n");
    var httpClient = addon.httpClient(req);
        "headers": {
          "Content-Type": "application/json",
          "Accept": "application/json"
        "url": '/wiki/rest/api/space'
      function(err, response, body) {
        if (err) {
          return console.log("ERROR: " + err);
          // res.send("Error: " + response.statusCode + ": " + err);
        } else {

        console.log(response.statusCode, body);

At the bottom there you can see I start to make a get request and was under the impression that I should be authenticated already due to the auth middleware. Can someone explain to me why my get request comes back as unauthorized 403 (“Request not in an authorized API scope”)?

If you weren’t authenticated at all, you should be getting an 401 error, so I’m guessing that is not the issue here. Your code sure looks fine to me.

I’d guess that you haven’t given your app the correct permission in the app descriptor, i.e. the atlassian-connect.json file. At the very least, you want to have a read scope, so something like this:

 "scopes": [

Hope that helps!

I do have this included like so:

  "scopes": [

in my atlassian-connect.json file. However, I’m not even sure if a webhook is exactly what I want or not? I want to hide this confluence add-on and have it respond to a jira add-on which should trigger it to get data from the confluence API and then send it back to the jira add-on to be displayed. Do you think a webhook is what I want here? Can I even trigger the confluence add-on from a custom event (aka a http request from the jira add-on to the confluence add-on endpoint url? Is that essentially what the available event triggers such as page_viewed do, except just from confluence?). I’m just concerned that I will go down this path and this route will not be feasible either from a communication perspective or an authorization perspective.

I’ll try to wrap my head around what you’re doing, so please bear with me and let me know if get it correctly.

You do have two add-ons, one for Confluence and one for Jira. Both are installed for the same Atlassian site (ex: YOURSUBDOMAIN.atlassian.net) and both run on the same server.

The code you posted above is from the Jira add-on, which has a route ‘/response’ that gets called by a Confluence webhook. Whenever that gets called, you want the Jira add-on to retrieve data from Confluence so you can do something, correct?

That all is correct except the code above lives on the Confluence add-on, and should be responsible for responding to the jira add-on and sending info back to it.

However, I was playing around with the Jira add-on and realized that if I make a client-side call to Confluence API from Jira add-on (using the AP.request…) it allows me to do this and returns valid data. Not sure why this occurs but it solves all my problems. Do you foresee any issues with this?

Well, if you can do everything you need using AP.request, then you should be all set. Just keep in mind that client-side calls are run with the permission of the logged in user which may are may not be sufficient for your needs.
A typical problem would be a user who is set up for Jira, but not for Confluence or who doesn’t have access to the Confluence space in question.
Apart from that: Sounds good and will definitely be easier on your backend.