Ghost failing for connecting to Admin URL

import axios from 'axios';

export default defineComponent({
  async run({ steps, $ }) {
    const GHOST_URL = 'VALID URL WAS PROVIDED HERE';
    const GHOST_ADMIN_API_KEY = VALID KEY WAS PROVIDED HERE';

    try {
      // Fetch posts from the Admin API
      const response = await axios.get(`${GHOST_URL}/ghost/api/admin/posts/`, {
        headers: {
          Authorization: `Ghost ${GHOST_ADMIN_API_KEY}`,
        },
      });

      const posts = response.data.posts;

      // Iterate through each post and check for 'automated-news' tag
      for (const post of posts) {
        if (post.tags.some(tag => tag.name === 'automated-news')) {
          console.log(`Updating post ID: ${post.id}`);
          // Hide the post by setting visibility to 'internal'
          await axios.put(`${GHOST_URL}/ghost/api/admin/posts/${post.id}/`, {
            posts: [{ visibility: 'internal' }]
          }, {
            headers: {
              Authorization: `Ghost ${GHOST_ADMIN_API_KEY}`,
            },
          });

          console.log(`Post "${post.title}" has been hidden from the homepage.`);
        }
      }

      return { success: true, message: 'Posts tagged with "automated-news" are now hidden.' };
    } catch (error) {
      console.error('Error:', error.response ? JSON.stringify(error.response.data, null, 2) : error.message);
      return { success: false, error: error.message, details: error.response ? error.response.data : null };
    }
  },
});

But the code run fails with this error message:
Error: {
“errors”: [
{
“message”: “Invalid token”,
“context”: null,
“type”: “BadRequestError”,
“details”: null,
“property”: null,
“help”: null,
“code”: “INVALID_JWT”,
“id”: “e3402e10-23f1-11f0-aee0-c5f3bd719293”,
“ghostErrorCode”: null
}
]
}

Hi there,

I’m curious why you’re trying to build this yourself instead of using the client library?

There’s also a full example in the docs for how to use the key in JS

Use Javascript Client is great.
But keep an eye on this problem:

I would use fetch instead of axios.

Here is my VUE/NUXT code for ContentApi (not for AdminApi). But should be the same.
I have overwritten the method makeRequest.

import GhostContentAPI from "@tryghost/content-api";

// https://ghost.org/docs/content-api/javascript/
const API_URL = 'http://localhost:2369';
const API_KEY = 'xxx';
const API_VERSION =  'v5.115';

// Create API instance with site credentials
export const ghostApi = new GhostContentAPI({
    url: API_URL,
    key: API_KEY,
    version: API_VERSION,
    // see: https://forum.ghost.org/t/tryghost-content-api-nuxt-3/56495
    // solution: https://forum.ghost.org/t/i-cant-use-local-ghost-content-ap/42502/12
    makeRequest: fetchAPI
})



function fetchAPI({url = API_URL, method='get', params = {key: API_KEY}, headers = {"Accept-Version":API_VERSION}}) {
    const apiUrl = new URL(url);
    Object.keys(params).map((key) =>
        // apiUrl.searchParams.set(key, encodeURIComponent(params[key]))
        apiUrl.searchParams.set(key, params[key])
    );

    // console.log('makeRequest', apiUrl.toString(),method, headers);

    return fetch(apiUrl.toString(), {method, headers})
        .then(async (res) => {
            // Check if the response was successful.
            if (!res.ok) {
                // You can handle HTTP errors here
                throw new Error(`HTTP error! status: ${res.status}`);
            }

            // console.log('fetchAPI', res);
            return {data: await res.json()};
        })
        .catch((error) => {
            console.error("Fetch error:", error);
        });



}

export async function getPosts(filter = '') {
    return await ghostApi.posts
        .browse({
            limit: "all",
            include: "tags",
            // include: "tags,authors",
            formats: "html,plaintext",
            filter: filter,
        })
        .catch(err => {
            console.error(err);
        });
}

export async function getSinglePost(slug) {
    return await ghostApi.posts
        .read(
            {slug: slug, include: "tags", formats: "html,plaintext"},
        )
        .catch(err => {
            console.error(err);
        });
}

... and so on