Learning objectives
After reading this article you will be able to:
- Understand what a webhook and a bot actually do
- Compare limits, permissions and maintenance cost
- Pick the right option for your case, or combine both
A webhook and a bot look alike, because both make a message show up in a Discord channel. The difference is the direction of the conversation. A webhook is an inbox slot: you send a POST and the message appears. A bot is a participant: it receives events, decides what to do and replies.
Picking the wrong one costs time. Someone who runs a bot just to announce "deploy finished" keeps a process alive for no reason. Someone who tries to build commands on a webhook finds out too late that it doesn't listen to anything.
What is a Discord webhook?#
It is a URL that Discord generates for a channel (in Channel Settings, Integrations, Webhooks). You call it with POST /webhooks/{id}/{token} and no authorization header: the token inside the URL is the credential. Anyone who has the URL can post to the channel.
Through the API, a webhook accepts content (up to 2000 characters), embeds (up to 10 per message), files, polls, and username and avatar_url to change the name and picture of each message. You must send at least one of content, embeds, components, a file or a poll. With ?wait=true the API returns the created message, and with thread_id it posts to a thread.
A minimal example with curl:
curl -X POST "$DISCORD_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{"content": "Deploy finished", "username": "CI"}'The same in Node.js, with the built-in fetch and no library (save it as .mjs, because of the top-level await):
const res = await fetch(process.env.DISCORD_WEBHOOK_URL + "?wait=true", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
embeds: [{ title: "New order", description: "Order #1234 paid", color: 0x57f287 }],
}),
});
if (res.status === 429) {
const { retry_after } = await res.json();
console.error(`Rate limited, retry in ${retry_after}s`);
} else if (!res.ok) {
console.error("Failed:", res.status, await res.text());
}What is a Discord bot?#
It is an application with its own user, created in the Developer Portal, that authenticates with a token. It can connect to the Gateway (a WebSocket connection) and receive events in real time: messages, members joining, reactions, slash commands. It can also receive interactions over HTTP if you set an Interactions Endpoint URL, without keeping the Gateway open. Once that URL is set, interactions stop arriving through the Gateway. Every request to the HTTP endpoint carries the X-Signature-Ed25519 and X-Signature-Timestamp headers, and you must verify the signature.
A bot can do almost anything a member can: assign roles, moderate, play audio, show menus and buttons. To build one, see how to make a Discord bot.
Webhook or bot: what is the practical difference?#
| Webhook | Bot | |
|---|---|---|
| Direction | Only sends messages | Sends and receives |
| Authentication | Token inside the URL | Bot token |
| Must stay online | No (it is just a URL) | Yes on the Gateway; no if HTTP only |
| Reads messages and events | No | Yes (message content needs the privileged intent) |
| Slash commands, buttons | No | Yes |
| Scope | One channel | Every server it was added to |
| Code | One HTTP call | A library such as discord.js or discord.py |
| Maintenance | Almost none | Update libraries, handle drops, reconnect |
One detail about reading: a bot without the privileged MESSAGE_CONTENT intent receives an empty content on messages, with exceptions such as messages that mention the bot, direct messages with it and messages it sends itself. Details in privileged intents.
When is a webhook enough?#
Choose a webhook when the flow is one-way and the trigger comes from outside Discord:
- monitoring alerts, a failed build or a finished deploy;
- a notification for a sale, a sign-up or a payment;
- an RSS, commit or changelog feed in a channel;
- a cron script that posts a daily summary.
The upside is simplicity. There is no bot token, no intents and no reconnecting. The cost is that a webhook only knows its channel: it does not know who is there, does not hear replies and does not go through role permissions.
When do you need a bot?#
You need a bot as soon as Discord becomes the input of the flow:
- slash commands (
/ticket,/play), buttons and menus; - moderation, welcome messages, automatic roles;
- replies that depend on the user, on history or on a database;
- music, voice or anything else that uses the Gateway;
- messages across several servers or channels chosen at runtime.
If the bot must answer around the clock, it needs a process that is always on. See how to keep a Discord bot online 24/7.
Which limits affect each one?#
The global API limit is 50 requests per second per bot, and routes have their own limits that Discord asks you not to hard-code. Requests without an authorization header, such as webhook calls, are limited by IP. When you go over, the API answers 429 with retry_after in seconds. Wait for the time in the Retry-After header or that field before retrying. The example above already reads the field. More in Discord 429 errors.
One more caution: if a webhook returns 404, stop using it (it was probably deleted). The documentation says not to keep retrying, because repeated attempts lead to a temporary restriction.
Content limits are the same for both: 2000 characters of text, 10 embeds per message and 6000 characters across all embed text combined.
Can you combine the two?#
Yes, and many projects do. The bot handles commands and events inside the server. External systems (CI, payment gateway, monitor) send alerts through a webhook, without depending on the bot being online at that moment. If the bot goes down, the alerts keep arriving.
A practical rule: start with a webhook if you only need to notify. Switch to a bot the first time you need to read or reply.
How to do this on Square Cloud#
A webhook needs no hosting, but the code that fires it has to run somewhere. A Gateway bot, on the other hand, needs a process that is always on. On Square Cloud, containers never go to sleep, and automatic restart (on by default for dashboard deploys) brings the bot back when the process exits with an error.
You deploy the bot in Node.js, Python, Java or another runtime by uploading a ZIP in the dashboard, or with the CLI, GitHub or the VS Code extension. The plan's RAM is a pool shared across your applications, with a minimum of 256 MB per background application such as a bot. The Hobby plan starts at R$12.49 per month. Keep the bot token and the webhook URL as the application's environment variables, not in the code.
To get started, see the Discord bot hosting page.
Bot hosting
Keep your bot online 24/7 with automatic restarts
FAQs
Does a Discord webhook need hosting?
The webhook itself does not, because it is just a Discord URL. What needs somewhere to run is your code that calls that URL, such as a script, a cron job or a CI service. A bot that uses the Gateway does: it is a process that stays connected all the time.
Can a webhook read messages or respond to commands?
No. An incoming webhook only posts messages to the channel. To read messages or react to users you need a bot (Gateway) or an app that receives interactions over HTTP.
Can I use a webhook and a bot together?
Yes, and it is common. The bot handles commands and events, and webhooks deliver alerts from external systems such as deploys, monitoring or payments.
Is it safe to keep the webhook URL in my code?
No. The token is part of the URL and anyone who has it can post to the channel. Keep it in an environment variable and generate a new URL if it leaks.
More in Bots
See all 33 articles- How much does it cost to host a Discord bot?The cost of hosting a Discord bot depends on RAM, uptime, database and outside services. Learn how to estimate your own bill and where the money goes.
- Running a bot on your phone or PC vs hosting itA bot on your PC or phone (Termux) goes offline when the device shuts down, sleeps or loses its network. Compare the three options and when each one fits.
- How to host a Discord bot 24/7To keep a Discord bot online 24/7, run its process on an always-on machine with automatic restarts. Compare your PC, a VPS with pm2 or systemd, and bot hosting.
- Why your Discord bot keeps going offline (and how to fix it)A Discord bot goes offline when the process dies, the token is invalid, an intent is disabled or memory runs out. Learn to diagnose each cause and fix it.