Why do I keep getting 404 errors when using the shopify-admin-api for js?

Topic summary

A developer is building a Discord bot using the Shopify Admin API client for JavaScript and encountering persistent 404 errors when attempting to retrieve order or product data.

The Issue:

  • Using @shopify/admin-api-client with endpoints like orders/${orderId} and products/count
  • All requests return 404 “Not Found” status, even with verified valid order IDs
  • The API client is configured with store domain, API version (2024-04), and access token

What’s Been Tried:

  • Multiple endpoints tested (orders by ID, product count)
  • Verified order IDs are correct
  • Code appears syntactically correct with proper async/await handling

Technical Details:

  • Response object shows status 404 with minimal error details
  • Console output includes garbled/reversed text in the response object
  • The discussion remains unresolved with no clear diagnosis of whether the issue stems from incorrect endpoint formatting, authentication problems, or API permission scopes
Summarized with AI on November 10. AI used: claude-sonnet-4-5-20250929.

I am making a discord bot and I have two commands, one of which I want to return a specific order, the bot deploys the commands with deploy-commands.js(not really relevant) and this specific command is called order.js, here it is:

const { SlashCommandBuilder } = require('discord.js');
const axios = require('axios');

const { createAdminRestApiClient } = require('@shopify/admin-api-client');

const client = createAdminRestApiClient({
  storeDomain: 'x.myshopify.com',
  apiVersion: '2024-04',
  accessToken: 'y',
});

module.exports = {
    data: new SlashCommandBuilder()
        .setName('order')
        .setDescription('Returns a order with a given order id.')
        .addIntegerOption(option =>
            option.setName('id')
                .setDescription('The id of the order you want info about!')
                .setRequired(true)),

    async execute(interaction) {

        const orderId = interaction.options.getInteger('id');
        const response = await client.get(`orders/${orderId}`);
        console.log(response)
        if (response.ok) {
            const body = await response.json();
            console.log(body);
        }
    },
};

All this seems like it should work, yet when I input a valid order ID or product ID I’ve tried both endpoints, neither of them work. Any ideas why? Thanks!

The output is:

Response {
  [Symbol(realm)]: null,
  [Symbol(state)]: {
    aborted: false,
    rangeRequested: false,
    timingAllowPassed: true,
    requestIncludesCredentials: true,
    type: 'default',
    status: 404,
    timingInfo: {
      startTime: 530421.735029,
      redirectStartTime: 0,
      redirectEndTime: 0,
      postRedirectStartTime: 530421.735029,
      finalServiceWorkerStartTime: 0,
      finalNetworkResponseStartTime: 0,
      finalNetworkRequestStartTime: 0,
      endTime: 0,
      encodedBodySize: 26,
      decodedBodySize: 0,
      finalConnectionTimingInfo: null
    },
    cacheState: '',
    statusText: 'Not Found',
    headersList: HeadersList {
      cookies: null,
      [Symbol(headers map)]: [Map],
      [Symbol(headers map sorted)]: null
    },
    urlList: [ URL {} ],
    body: { stream: undefined }
  },
  [Symbol(headers)]: HeadersList {
    cookies: null,
    [Symbol(headers map)]: Map(25) {
      'date' => [Object],
      'content-type' => [Object],
      'transfer-encoding' => [Object],
      'connection' => [Object],
      'x-sorting-hat-podid' => [Object],
      'vary' => [Object],
      'referrer-policy' => [Object],
      'x-frame-options' => [Object],
      'x-request-id' => [Object],
      'server-timing' => [Object],
      'x-shopify-stage' => [Object],
      'content-security-policy' => [Object],
      'x-content-type-options' => [Object],
      'x-download-options' => [Object],
      'x-permitted-cross-domain-policies' => [Object],
      'x-xss-protection' => [Object],
      'x-envoy-upstream-service-time' => [Object],
      'x-dc' => [Object],
      'cf-cache-status' => [Object],
      'report-to' => [Object],
      'nel' => [Object],
      'server' => [Object],
      'cf-ray' => [Object],
      'content-encoding' => [Object],
      'alt-svc' => [Object]
    },
    [Symbol(headers map sorted)]: null
  }
}

Also I tried this endpoint

async execute(interaction) {

        const orderId = interaction.options.getInteger('id');
        const response = await client.get(`products/count`);
        console.log(response)
        if (response.ok) {
            const body = await response.json();
            console.log(body);
        }
    },

By simply changing my code to this: So I can no longer have the possibility of my order id being wrong, I know it doesn’t make sense to have a order command output the product count but it still returns this:

Response {
  [Symbol(realm)]: null,
  [Symbol(state)]: {
    aborted: false,
    rangeRequested: false,
    timingAllowPassed: true,
    requestIncludesCredentials: true,
    type: 'default',
    status: 404,
    timingInfo: {
      startTime: 559095.311115,
      redirectStartTime: 0,
      redirectEndTime: 0,
      postRedirectStartTime: 559095.311115,
      finalServiceWorkerStartTime: 0,
      finalNetworkResponseStartTime: 0,
      finalNetworkRequestStartTime: 0,
      endTime: 0,
      encodedBodySize: 0,
      decodedBodySize: 0,
      finalConnectionTimingInfo: null
    },
    cacheState: '',
    statusText: 'Not Found',
    headersList: HeadersList {
      cookies: null,
      [Symbol(headers map)]: [Map],
      [Symbol(headers map sorted)]: null
    },
    urlList: [ URL {} ],
    body: { stream: undefined }
  },
  [Symbol(headers)]: HeadersList {
    cookies: null,
    [Symbol(headers map)]: Map(25) {
      'date' => [Object],
      'content-type' => [Object],
      'transfer-encoding' => [Object],
      'connection' => [Object],
      'x-sorting-hat-podid' => [Object],
      'vary' => [Object],
      'referrer-policy' => [Object],
      'x-frame-options' => [Object],
      'x-request-id' => [Object],
      'server-timing' => [Object],
      'x-shopify-stage' => [Object],
      'content-security-policy' => [Object],
      'x-content-type-options' => [Object],
      'x-download-options' => [Object],
      'x-permitted-cross-domain-policies' => [Object],
      'x-xss-protection' => [Object],
      'x-envoy-upstream-service-time' => [Object],
      'x-dc' => [Object],
      'cf-cache-status' => [Object],
      'report-to' => [Object],
      'nel' => [Object],
      'server' => [Object],
      'cf-ray' => [Object],
      'content-encoding' => [Object],
      'alt-svc' => [Object]
    },
    [Symbol(headers map sorted)]: null
  }
}