Build a sneaker price Discord bot

This example adds a /price command to a Discord server. A user types a style code, and the bot answers with the lowest ask on each marketplace. It uses discord.js and the Barcodes.gg resale price API.

Last checked:

Before you start

  • Node.js 18 or later, for the built-in fetch.
  • A Discord application with a bot user. You need its application ID and bot token from the Discord developer portal. Invite the bot to your server with the bot and applications.commands scopes.
  • A Barcodes.gg API token with the prices ability. Tokens on Standard and higher plans can carry it.

Install the library:

npm install discord.js

Register the /price command

Run this script once. It tells Discord that the bot has a /price command with one required option:

// register.mjs
import { REST, Routes, SlashCommandBuilder } from "discord.js";

const price = new SlashCommandBuilder()
  .setName("price")
  .setDescription("Resale prices for a sneaker style code")
  .addStringOption((option) =>
    option.setName("style_code").setDescription("For example DZ5485-612").setRequired(true));

const rest = new REST().setToken(process.env.DISCORD_TOKEN);
await rest.put(Routes.applicationCommands(process.env.DISCORD_APP_ID), { body: [price.toJSON()] });
console.log("Registered /price");

Answer the command

The bot sends one request per command and writes one line per marketplace row:

// bot.mjs
import { Client, GatewayIntentBits } from "discord.js";

const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.on("interactionCreate", async (interaction) => {
  if (!interaction.isChatInputCommand() || interaction.commandName !== "price") return;
  const styleCode = interaction.options.getString("style_code", true).trim();
  await interaction.deferReply();

  const res = await fetch(`https://barcodes.gg/api/v2/prices/${encodeURIComponent(styleCode)}`, {
    headers: { Authorization: `Bearer ${process.env.BARCODES_TOKEN}` },
  });
  const body = await res.json();
  if (!res.ok || body.error) {
    await interaction.editReply(`No resale prices found for ${styleCode}.`);
    return;
  }

  const lines = body.results.sites.flatMap((site) => {
    const asks = site.sizes.map((size) => size.price).filter((price) => price !== null);
    if (asks.length === 0) return [];
    const market = site.market ? ` ${site.market}` : "";
    return [`${site.site}${market}: from ${Math.min(...asks)} ${site.currency} (${asks.length} sizes)`];
  });
  const note = body.results.is_stale ? "\nThe newest price is older than 24 hours." : "";
  await interaction.editReply(`**${styleCode}**\n${lines.slice(0, 15).join("\n")}${note}`);
});

client.login(process.env.DISCORD_TOKEN);

Run it

export DISCORD_TOKEN=your-bot-token
export DISCORD_APP_ID=your-application-id
export BARCODES_TOKEN=your-barcodes-token
node register.mjs
node bot.mjs

In Discord, type /price DZ5485-612. The bot shows one line for each marketplace row with a price, for example StockX in the Spanish market and Alias in USD.

Calls, limits and next steps

  • Each command uses one call. A style code without cached prices is not charged.
  • Keep the Barcodes.gg token on the server that runs the bot. Do not put it in a public repository.
  • To save calls on a busy server, keep each answer in memory for a few minutes and reuse it.
  • To show one size, read size.eu or size.us from the same answer and filter the rows.
  • To answer from a barcode, call /api/v2/prices/barcode/{barcode}. The answer then holds the size of that barcode only.

All fields are described on the sneaker resale price API page and in the documentation.

Get resale prices by API

Resale prices are on Standard (€49 per month) and higher plans. One answered request uses one call. A product without cached prices is not charged.

Guides

StockX, GOAT and Alias are trademarks of their owners. Barcodes.gg is not affiliated with them.