Getting started

Invite the bot, build a form, publish a panel. Most of it happens in the dashboard; three things cannot, and they are the three that cause the “it installed but nothing happens” support ticket.

1. Add the bot

The Add to Discord button on this site is a redirect the API builds from its own client id, so it always invites the deployment you are actually looking at. It carries no server id, which is why Discord shows you the picker rather than assuming.

The invite requests nine permissions. They are the set the features need, and every one of them is load-bearing somewhere: manage roles to grant what an accept grants, ban members to lift a ban when an appeal succeeds, manage channels for ticket panels. An invite missing one produces a feature that silently does nothing, which is the failure the dashboard’s invite flow exists to prevent.

2. Turn on the two intents

Only relevant if you are running your own instance or a dedicated bot; on the hosted deployment these are already on. In the Discord Developer Portal, open your application, then Bot → Privileged Gateway Intents, and switch on:

  • Server Members Intent — without it the welcomer, the verification gate and the auto-kick timer never see anyone join, and nothing notices when someone leaves.
  • Message Content Intent — ticket transcripts and /poll's typed close time read message text.

Save the page. Those are the only two. Ban appeals run on the ban event from the Server Moderation intent, but that one is not privileged, has no switch in the portal, and Appealy requests it on its own.

If either switch is off, Discord refuses the connection, and Appealy tells you which switch, with a link to the page it is on. A self-hosted bot logs it and keeps checking every 30 seconds, so it comes online by itself once you tick the box, without a restart. A dedicated bot shows the message on its dashboard panel; save the token again there once the switches are on.

A bot in 100 or more servers needs Discord's approval for each intent, requested from the same page. Below that, the switches are all it takes.

3. Register the slash commands

Once per deployment, and again after changing a command:

cd bot && deno task sync-commands

This is deliberately a deploy step rather than something that happens on boot. Discord allows 200 global command creates per day per application, and a bot that registers on every start spends that budget on crash loops — at which point it cannot start at all until the window resets, which is a far worse outage than whatever caused the loop.

4. Build a form

Open the dashboard and pick your server. A form is a list of questions plus what happens when one is accepted: which roles are granted, which are removed, what the applicant is sent, and where it is logged.

Two things worth setting up front:

  • Cooldowns and limits. A form with neither is a form one person can submit forty times. /reset-cooldown exists for when you want to let a specific person retry.
  • Answer validation. Questions can require a minimum and maximum length, and optionally a regular expression — ^[A-Za-z0-9_]{3,16}$ for a Minecraft username, say. It is enforced at both submission points, the in-server modal and the DM flow, through the same shared code so the two cannot drift apart.

5. Publish a panel

A panel is the message with the button on it. /panel creates and publishes one; the dashboard manages them. This is the step that makes a form reachable — a form with no panel exists and nobody can find it.

Applicants can also use /apply, and /forms lists what is available in the server.

The commands

Seventeen, and this is all of them:

Command Does
/apply Apply for an application form in this server
/forms List all application forms configured in this server
/panel Manage application panels
/ticket-panel Manage ticket panels
/role-menu Manage self-assignable role menus
/verify-setup Configure and publish server verification
/anti-raid Configure join-velocity raid detection
/giveaway Manage giveaways
/poll Create and publish a poll
/reset-cooldown Clear one user’s cooldown or limit for one application form
/dashboard Get a link to the web dashboard for this server
/botstats Show bot health and usage stats
/ping Check the bot’s latency
/export_applications Export submitted applications to a CSV file
/export Export all of this server’s Appealy data as a JSON file (owner only)
/import-appealy Import another server’s Appealy setup from an /export file
/import-appy Import Appy application submissions into an Appealy form (owner only)

/export is not a formality. It writes every form, panel, submission and answer this server has as one JSON file, and /import-appealy reads it back. Leaving is a supported operation rather than something you negotiate with support — which is the point of it existing before you need it.

Signing in

The dashboard signs you in through Discord in a popup rather than by navigating the page away, so the console keeps its state instead of being torn down and rebuilt around a redirect. If the popup is blocked — no user gesture, or Discord’s own in-app browser, which does not give a popup an opener to talk back through — it falls back to a full-page redirect on its own.

Nothing sensitive crosses that boundary. The session is an httpOnly cookie the browser holds and no script can read; the message the popup posts back carries only whether it worked.


Next: Ban appeals, or Review outcomes if you are setting up a staff application with more than one possible yes.