Campaign Kit docs
v0.1.0
Get help
● Start · Local install

Quick start
running on your computer.

Install the dependencies, create the database, start the API, Mini App and admin, create your owner account and open the Mini App in a normal browser with a signed Telegram login. Every command on this page was run against this release.

01Before you start

You need Node.js 22, pnpm 10 and a running PostgreSQL 16 on your computer (details in Requirements). Check them:

node -v
pnpm -v
psql --version

You also need a Telegram bot token for the first campaign. Creating one takes two minutes: see Create the bot with @BotFather. Locally the bot cannot receive messages (Telegram only delivers to https), but the token is needed to sign the Mini App login.

021. Install and configure

From the repository root:

pnpm install
cp .env.example .env

Open .env in a text editor and fill the three required secrets. Generate each value with the command next to it and paste the output after the =:

VariableGenerate withRule
ENCRYPTION_KEYopenssl rand -hex 32Exactly 64 hex characters
ADMIN_JWT_SECRETopenssl rand -hex 32At least 32 characters
ABUSE_HASH_SALTopenssl rand -hex 16At least 16 characters

Leave everything else as it is for local development. The defaults point at localhost. Do not add NODE_ENV to .env: the web apps share this file and it would break their builds.

If a value is wrong

The API refuses to start and lists each problem, for example ENCRYPTION_KEY: must be 64 hex characters. Fix the line in .env and start again.

032. Create the database

createdb campaign_kit
pnpm db:migrate

The second command prints migrations applied. It uses DATABASE_URL from .env (default postgres://localhost:5432/campaign_kit). If your PostgreSQL needs a user and password, put them in that URL: postgres://user:password@localhost:5432/campaign_kit.

043. Start everything

pnpm dev

This starts all three apps in parallel:

AppURL
APIhttp://localhost:8787 (check http://localhost:8787/health, it answers {"ok":true,"version":"0.1.0"})
Mini Apphttp://localhost:5173
Adminhttp://localhost:5174

The API also starts the bot broadcast worker in the same process. Nothing is sent until you create a broadcast.

054. Create your owner account

Open http://localhost:5174. On a fresh database the admin shows Set up your admin: enter your name, e-mail and a password of at least 10 characters. This first account is the owner with full control. The setup form closes for good once an admin exists.

Then click New campaign, enter a name and a slug (lowercase letters, digits and -, 3–40 characters, for example my-campaign). The slug appears in URLs and cannot be shared by two campaigns.

065. Connect the bot and set the Mini App URL

The new campaign opens its Launch checklist (Settings → Launch).

  1. Bot tokenPaste the token from @BotFather and click Validate & connect. Locally you will see Webhook skipped — the API URL is not https. That is expected: the token is saved and the login works; only incoming bot messages and Stars payments need https.
  2. Mini App URLEnter http://localhost:5173 and Save. The admin accepts localhost for testing; everything else must be https.

076. Open the Mini App in a browser

Outside Telegram the Mini App has no Telegram login, so it shows Open in Telegram. There is no bypass. To test in a browser, sign a real login with your campaign's own bot token:

pnpm dev:initdata <slug>

It prints the signed login (valid for 24 hours), a VITE_DEV_INIT_DATA= line, a browser URL like http://localhost:5173/?c=<slug>#tgWebAppData=… and a curl example. Open the URL. Optional arguments set the test user: pnpm dev:initdata <slug> <telegramId> <firstName>.

While the campaign is still a draft, the game already works so you can test it with your own account. Players only see it after you set it live.

It fails with a message about the bot token

Connect a bot to the campaign first (step 5). If it says the token cannot be decrypted, ENCRYPTION_KEY in .env differs from the one used when the token was saved: paste the bot token again in the admin.

08What next