API Bouncer

Buy me a coffee

How to Build a Discord Bot with Free APIs

Discord bots are one of the most fun things you can build as a developer. They're interactive, people actually use them, and they're a great excuse to explore free APIs. In this guide, we'll build a multi-command Discord bot that pulls data from several free APIs — jokes, weather, trivia, and random facts.

What you'll need

Step 1: Create a Discord application

Head to the Discord Developer Portal and click "New Application." Give it a name like "API Bot," then navigate to the Bot tab and click "Add Bot." Copy the token — you'll need it soon. Under the OAuth2 tab, select the "bot" scope and the permissions you need (Send Messages, Read Message History, Embed Links). Use the generated URL to invite the bot to your server.

Step 2: Set up the project

Create a new directory and initialize the project:

mkdir discord-api-bot && cd discord-api-bot npm init -y npm install discord.js dotenv

Create a .env file to store your token. Never commit this file to version control.

DISCORD_TOKEN=your_bot_token_here

Step 3: Choose your APIs

We'll use three free APIs that require no authentication — perfect for a bot:

You can browse hundreds more options on our API search page to find APIs that match your bot's personality.

Step 4: Write the bot

Create an index.js file with the following structure:

require('dotenv').config(); const { Client, GatewayIntentBits, EmbedBuilder } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent ] }); client.on('ready', () => { console.log(`Logged in as ${client.user.tag}`); }); client.on('messageCreate', async (message) => { if (message.author.bot) return; if (message.content === '!joke') { const res = await fetch('https://v2.jokeapi.dev/joke/Programming?type=single'); const data = await res.json(); message.reply(data.joke); } if (message.content.startsWith('!weather')) { const city = message.content.slice(9).trim() || 'New York'; // First, geocode the city name const geoRes = await fetch( `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(city)}&count=1` ); const geoData = await geoRes.json(); if (!geoData.results?.length) { return message.reply('City not found. Try "!weather London".'); } const { latitude, longitude, name } = geoData.results[0]; const wxRes = await fetch( `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t_weather=true` ); const wx = await wxRes.json(); const cw = wx.current_weather; const embed = new EmbedBuilder() .setTitle(`Weather in ${name}`) .addFields( { name: 'Temperature', value: `${cw.temperature}°C`, inline: true }, { name: 'Wind', value: `${cw.windspeed} km/h`, inline: true } ); message.reply({ embeds: [embed] }); } if (message.content === '!trivia') { const res = await fetch('https://opentdb.com/api.php?amount=1&type=multiple'); const data = await res.json(); const q = data.results[0]; // Decode HTML entities const decode = (s) => s.replace(/&/g,'&').replace(/</g,'<') .replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,"'"); const answers = [...q.incorrect_answers, q.correct_answer] .sort(() => Math.random() - 0.5) .map((a, i) => `${i + 1}. ${decode(a)}`); message.reply(`**${decode(q.question)}**\n${answers.join('\n')}\n\n||Answer: ${decode(q.correct_answer)}||`); } }); client.login(process.env.DISCORD_TOKEN);

How it works

The bot listens for messages starting with ! prefixes. Each command hits a different API, formats the response, and sends it back to the channel. The weather command uses an embed for a cleaner look, and the trivia command uses Discord's spoiler syntax to hide the answer.

Step 5: Run and test

node index.js

In your Discord server, try !joke, !weather Tokyo, and !trivia. You should see responses within a second or two.

Adding more commands

The pattern is always the same: fetch data from an API, format it, send a reply. Here are ideas for expanding your bot:

Check out our API categories page for inspiration — the Animals, Entertainment, and Science categories are especially popular for bots.

Deployment tips

Running the bot on your laptop isn't practical long-term. Here are affordable hosting options:

Whichever you choose, make sure to set your bot token as an environment variable — never hardcode it in your source files.

What's next

Once the basic bot works, consider upgrading to slash commands (Discord's modern interaction model), adding a cooldown system to prevent API rate-limit issues, or storing user preferences in a SQLite database. The core idea stays the same: your bot is a bridge between Discord users and the massive ecosystem of free APIs out there.