Why Can’t I Use an API Token to Install an App via the Marketplace GraphQL API?

Hello everyone,

I’m attempting to install an app from the Marketplace using the GraphQL endpoint provided by Atlassian. However, my request fails due to the following error:

{
  "errors": [
    {
      "message": "Auth category: API_TOKEN is not allowed in service marketplace_store",
      "extensions": {
        "allowedAuth": ["UNAUTHENTICATED", "SESSION"],
        "presentedAuth": "API_TOKEN",
        "errorSource": "GRAPHQL_GATEWAY",
        "statusCode": 403
      }
    }
  ],
  "data": {
    "marketplaceStore": null
  }
}

It appears that the service marketplace_store does not permit the use of API tokens (presentedAuth: "API_TOKEN"). Instead, it only supports UNAUTHENTICATED or SESSION authentication.

Could anyone shed some light on why API tokens aren’t allowed for this installation endpoint, or how to properly authenticate so that I can successfully install an app? I’ve tried including the token in the Authorization header (e.g., Bearer <MY_TOKEN>), but it still fails. Any guidance on session-based or other valid authentication methods for Marketplace installations would be greatly appreciated!

Thank you in advance!

Code demo:

const siteUrl = "https://cooking-book4.atlassian.net";
const my_email = "";
const my_token = "";
let cloudId = "";

const makeRequest = async (query, variables) => {
  let token = Buffer.from(`${my_email}:${my_token}`).toString("base64"); // replace my-email and my-token with your email and token

  const response = await fetch("https://api.atlassian.com/graphql", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-ExperimentalApi": "compass-beta, compass-prototype",
      Authorization: `Basic ${token}`,
    },
    body: JSON.stringify({
      query,
      variables,
    }),
  });
  return response.json();
};

// INSTALL APP
const queryInstall = `
  mutation InstallApp($input: MarketplaceStoreInstallAppInput!) {
  marketplaceStore {
      installApp(input: $input) @optIn(to: "MarketplaceStoreInstallAppM1") {
        ...InstallResult
      }
    }
  }
  fragment InstallResult on MarketplaceStoreInstallAppResponse {
    taskId: id
    status
  }
`;
makeRequest(queryInstall, {
  input: {
    appKey: "APP_KEY", // replace APP_KEY with your app key
    target: {
      cloudId,
      product: "JIRA",
    },
  },
}).then((response) => {
  console.log(JSON.stringify(response, null, 2));
});