Documentation
Everything a server owner needs. For the HTTP API, see the API reference.
Getting started
Invite the bot, sign in at poi-bot.com with Discord, and pick your server. Only servers where you have Manage Server or Administrator appear.
Every server has a Setup checklist that reads your live configuration, so it always reflects reality rather than a stored step counter.
Permissions
The invite link grants exactly the permissions the bot uses and nothing more. Never grant Administrator.
The bot's role must sit ABOVE any role it manages. Discord enforces role hierarchy server-side, so a verified role or a punished member ranked above the bot makes the action fail regardless of permissions.
The invite grants permission integer 1099796933814, verified against discord.js by the bot’s own permission check.
Moderation
Automod runs on every message. Rules are word filters, link allowlists, invite blocking, mention and caps thresholds, message rate, duplicate detection, and attachment extensions.
There is deliberately no regular-expression rule type. A tenant-authored pattern evaluated on every message is a denial-of-service risk against every server sharing the bot.
Anyone with Manage Messages is exempt automatically, so moderators cleaning up a raid never trip their own rules. A message that breaks several rules produces only the most severe punishment, never a stacked warn and timeout and ban.
Selling things
You supply your own Stripe keys. Money moves between your Stripe account and your customers; poi-bot never touches it and never holds funds.
Keys are encrypted with AES-256-GCM under a per-row key before they are stored, and decrypted only in memory for the duration of one API call. They are never shown back to you and never written to a log.
The webhook secret matters as much as the API key. Without it, payments succeed but nothing is ever delivered, because the bot never learns the payment happened.
Fulfilment is idempotent. Stripe redelivers webhooks routinely, and a redelivery will not charge twice or deliver twice.
Plans
Plans are per server, not per account. Moderation, tickets, and automation are free. The paid tiers gate the things that cost real money to run: commerce, SellAuth, longer analytics retention, and higher limits.
A failed payment does not cut you off immediately. Stripe retries for several days first, and access continues throughout.
Downgrading never deletes anything. Data over the new limit stops being used until you upgrade again or remove it yourself.
What the bot stores
Message content is stored in only two places, both opt-in or short-lived: ticket transcripts (written when a ticket closes, visible to server staff) and snipe (memory only, capped at five per channel, discarded after an hour, off by default).
Analytics are aggregate counts of messages, joins and leaves per day. No message content and no per-user records.
Automod stores a snapshot of an offending message on the case record, so a moderation decision can be justified and appealed.
Commands
Registered globally when the bot starts. Moderation commands are permission-gated by Discord itself, so a member without the underlying permission cannot invoke them.
Server setup
Commerce
ProModeration
Messages
Community
Webhooks
Five endpoints matter, and only the first two are ones you configure. Every signed endpoint verifies against the exact bytes received, not a re-serialised object, because re-serialising is how signature checks quietly stop working.
POST /api/webhooks/stripe/[serverId]Your server's Stripe endpoint. Point a Stripe webhook here and paste the signing secret into the Commerce page. Signature is verified against that secret before anything is read; a forged or tampered body is rejected. Delivery is idempotent on the event id, so Stripe's redeliveries are safe.
POST /api/webhooks/sellauth/[serverId]The same contract for SellAuth orders on Pro and above. Orders sync into the same table the Stripe path writes to, so /orders and the dashboard show one history rather than two.
POST /api/webhooks/platformOur own Stripe account, for poi-bot subscription billing. This is what moves a server between plans. It is not something you configure.
POST /webhook/push (on the bot)The dashboard-to-bot channel, served by the Railway deployment rather than Vercel. Authenticated with an HMAC signature over the exact request bytes using BOT_WEBHOOK_SECRET. It carries a server id and a reason, never credentials.
GET /api/statusPublic health summary: whether the dashboard can currently reach the gateway, and how long that round trip took. Safe to point an uptime monitor at.
When something does not work
- Bot appears offline: check the status band first, then that the Railway deployment is running and not rate-limited by Discord.
- A role is not being granted: the bot’s role is below the target role. Move it up in Server Settings, then Roles.
- Payment succeeded but nothing was delivered: the webhook secret is missing or wrong. Check the Commerce page and the audit log.
- Automod is not firing: confirm it is enabled, that the rule is enabled, and that the author does not have Manage Messages. Moderators are exempt by design.
- A change has not taken effect: configuration reaches the bot immediately when the push succeeds, and within 30 seconds otherwise.