Skip to content

Admin panel and settings

Pavel Erokhin edited this page Oct 22, 2026 · 12 revisions

The backend serves a web admin panel, Allay Room, at /admin. There you change every setting, manage admin accounts, and see what the backend does. On a self-hosted backend its sidebar links the project's source, issues, discussions, and releases.

What the panel shows

  • Questions, cost, players, servers, errors and cancellations, answer times, tokens, web searches, the cost of a question, models, tools, and the busiest players, by day.
  • Each run's numbers and the shape of its trace: steps, models, tools and whether they worked, tokens, and timings, with the player and the server it ran on. Since 6.9 the words in a trace are sealed; an owner opens one run with Show text on its page to look into a reported problem, after a confirmation, and every look lands in the audit log.
  • The audit log, filtered by area (accounts, settings, players, licenses, payments, opened runs) and by who, with each change as its old and new value.
  • With billing on: licenses, payments, revenue, refunds, budgets granted by hand, and blocked licenses. “Refund and revoke” on a license's page returns every payment through the bot, stops its subscription, tells the payer in Telegram, and revokes the license for good: its key answers LICENSE_INVALID, and the server takes a new license with /allay link. Telegram refunds only whole payments, so there is no partial refund. Delete removes a license and its budget windows; its payments stay. A paid license without a refund sends you to “Refund and revoke” first, and only an owner may delete it anyway, after a warning about the payer's rights and a second agreement.

Nobody sees what players asked, what Allay answered, what tools were given and returned, or what Allay remembers about a player. The backend never sends those to the browser, whatever the role. Since 6.4 the panel names players with the name and UUID of their last question and shows their faces (see Security and privacy).

Statistics come from a runs collection, one document per run with numbers only, kept 730 days, plus daily rollups whose sums stay forever and whose lists of players go after 730 days.

Servers

The Servers page lists each Minecraft server with its name (server.name in the plugin's config, Allay 6.5; unique on the backend), its domain (server.address, Allay 6.4), its license, the game software and the plugin's version (Runtime), questions, and when it was last used. Admins also see the IP it connects from; one marked internal reaches the backend over a private network they share, like a plugin on the same machine. Tables never show a MOTD.

Clicking a server opens its page (GET /api/admin/servers/{tenant}/{server id}): its details, its MOTD line by line in a block of its own (the only place the panel shows a MOTD), its license as a button, every player who asked there, and its newest runs. A run names its server as a button too.

Licenses

With billing on, the Licenses page lists each license by the name its owner gave a server behind it (server.name), else the name the license got at /allay link, else its id, its server and domain, status, plan, paid period, and a budget bar that fills as money goes: a full bar means the limit is spent. A license's page shows its plan (a hand-given budget of Infinity's size counts as Infinity), the paid date with the days left, what's left of the budget now, when it resets with how many days it lasts at the open windows' average spend a day, its details (a budget given by hand stands in for a payment on a license nobody paid for), the servers behind it as cards that open their pages, its budget windows with the same bars, and its payments. Actions are grouped: Budget (grant, extend, and for owners Grant Infinity), Access (block, refund and revoke), and Delete. An owner edits the license's stored name, shown only while none of its servers has a name of its own, and the language the bot writes in (PATCH /api/admin/licenses/{id} with name and language).

Notify license holders, an owner's button on the Licenses page, sends one text through the bot to every license's Telegram chat, 20 a second (POST /api/admin/licenses/notify with { text, licenses? }, up to 3000 characters, optionally only the listed licenses). It answers how many got it, failed, or have no chat yet, and the audit log keeps the counts, not the text. Use it for a breach notice the servers' owners must get without delay (GDPR art. 33(2)).

Players

The Players page lists players with their face, name, servers, questions, errors, tokens, average answer time, cost, language, and first and last question. Players who last asked before 6.4 show their pseudonym until their next question. The search is a dropdown: it takes the start of a name, a UUID, or a pseudonym, picking a player opens them, and Enter filters the table. A player's page adds their UUID, operator status, every server they asked on with their own numbers there, questions by day and by hour, and their kinds of runs, models, and tools.

A player's page has Actions for admins, on one server the player asked on:

  • Clear session: Allay forgets the conversation so far, as after the player's own /allay new. Memories stay.
  • Block and Unblock: a blocked player gets PLAYER_BLOCKED on that server until someone unblocks them. Blocked players on the Players page lists every block, erased players too.
  • Erase: memories, deaths, the player's state, session, agents' threads, and traces go, and runs keep only numbers.

The backend finds who a pseudonym is in the player directory (everyone who asked since 6.4), among the players who agreed to the notice on that server (since 6.1), or among those with memories there. When none knows them, there's no session to clear, and erasing removes what's left: their runs' ties and traces. Erase a player under the list picks the player by name from every server's players, with face, UUID, and server, and still takes a UUID or a pseudonym typed in, with the server to erase them on. Every action lands in the audit log under the pseudonym.

Create the first account

On a self-hosted backend (SELFHOSTED=1, with PLUGIN_TOKEN set in the backend and the plugin):

  1. In the game, as an operator, run /allay init.
  2. The plugin shows a link that works once, for 30 minutes. A new /allay init replaces a pending link.
  3. Open it: the setup page makes you the panel's owner.

A backend with billing on prints a setup code to its log at start instead.

With ADMIN_USERNAME and ADMIN_PASSWORD (or ADMIN_PASSWORD_HASH) in the environment, that account is the owner, setup is off, and the panel goes straight to sign-in.

Recover a forgotten password

  1. On a self-hosted backend that already has an account, run /allay init again.
  2. This time the link opens a recovery page, with the same rules: once, for 30 minutes.
  3. Enter your name and a new password. Every other session of that account ends, and the audit log notes it.

An owner can also set a new password for anyone on the Accounts page, typed or made with Generate (20 random characters, shown and copied to give to the person). On a backend with billing on, that's the only way back. The environment's admin is the last resort: its password lives in ADMIN_PASSWORD or ADMIN_PASSWORD_HASH, never in the panel.

Roles

  • Owners do everything, other accounts included.
  • Admins change settings and billing, and clear, block, and erase players.
  • Viewers only read: pseudonyms and numbers, without players' names, faces, or ids (since 6.9), and without payers' Telegram ids.

Every change lands in the audit log with its old and new value, secrets masked, kept 730 days (365 before 6.9). The API shows only the last four characters of a secret.

Sessions and sign-in

A session lasts 7 days from its last use, in an HttpOnly, SameSite=Strict cookie. Sign-in locks for 15 minutes after 5 wrong passwords for one name, or 10 from one address (an IPv6 /64 counts as one). Behind a proxy, set TRUSTED_PROXIES, or every visitor shares the proxy's address.

Settings

Each setting shows a plain name next to the name of the environment variable it was before 5.7. Changes apply to the next run, except those marked “after a restart”. A self-hosted backend hides the billing and Telegram groups. The model field marks the recommended model and offers it in one click. The environment card shows where the secrets key comes from with its last four characters, never more.

Model

Setting What it does Default
OPENROUTER_API_KEY OpenRouter key for runs on this backend's own key required for answers
OPENROUTER_API_URL OpenRouter API address https://openrouter.ai/api/v1
OPENROUTER_API_MODEL The agent's model; ~anthropic/claude-haiku-latest is the recommended one. It must support tool calling: perplexity/sonar* won't do ~anthropic/claude-haiku-latest (since 6.9)
OPENROUTER_REASONING_EFFORT How hard a model that reasons thinks: low, medium, high, or unset, which sends nothing, so OpenRouter leaves it to the model and Claude models don't reason at all medium (since 6.9)
OPENROUTER_DATA_COLLECTION deny routes requests only to providers that don't store or train on them; allow lets OpenRouter pick any deny (since 6.9)
API_NAME The name OpenRouter shows for this backend's requests allay

Search

Setting What it does Default
PERPLEXITY_API_KEY Perplexity's Search API for web search on the backend's own key unset, so SEARCH_MODEL searches
SEARCH_MODEL Online model for web search without a Perplexity key, and for servers with their own key perplexity/sonar
OPENROUTER_API_CTX Search context size of the online model: low, medium, high medium

Limits

Setting What it does Default
TOOL_TIMEOUT_MS How long to wait for the plugin's tool result 15000
MAX_AGENT_STEPS Model calls per question 26 (since 6.9)
MAX_TASK_STEPS Model calls per wake of an automation agent 32 (since 6.9)
MAX_ACTIVE_RUNS Streaming questions at once 200
SSE_PING_MS Ping interval that keeps proxies from closing the stream 15000
MEMORY_MAX Memories a player may keep, places included. Since 6.9 200
DEATHS_MAX Deaths kept per player, newest first. Since 6.9 100
CALC_TIMEOUT_MS How long exact_calculations gives one expression 1000

Sessions

Setting What it does Default
CHAT_TTL_SECONDS How long a chat session lives after the last question 2592000, 30 days (since 6.9)
PUBLIC_CHAT_TTL_SECONDS How long a server's thread of public questions lives after the last one 7200
TASK_CHAT_TTL_SECONDS How long an automation agent's thread lives after its last wake 7200
CHAT_FOLD_TOKENS A session folds into its summary past this many tokens 32000
CHAT_KEEP_TOKENS About how many tokens of the newest exchanges stay verbatim after a fold 12000
CHAT_MAX_TOKENS Past this many tokens, a session folds before the answer 42000

Tracing

Setting What it does Default
TRACE_SAMPLE The share of runs traced; 0 turns tracing off. After a restart 1
TRACE_DAYS How long traces stay, in days. After a restart 30 (since 6.9)

Billing (hosted backends only)

Setting What it does Default
PLAN_WEEK_STARS, PLAN_MONTH_STARS, PLAN_YEAR_STARS Prices in Stars. PLAN_STARS=week=1,month=1,year=1 from before 5.7 still sets all three, for a test payment you refund 150, 500, 10000
PLAN_WEEK_BUDGET, PLAN_MONTH_BUDGET, PLAN_YEAR_BUDGET What a period's runs may cost, in US dollars (a year's per 30 days) 0.75, 3, 6
PLAN_INFINITY_BUDGET What Infinity's 366 days may cost in all, in US dollars. Never sold: an owner grants it on a license's page. Since 6.9 1000
BYOK_PER_MINUTE, BYOK_PER_DAY, BYOK_CONCURRENT Limits for a server with its own key, per license 20, 2000, 4
BYOK_ACTIVE_RUNS Questions at once from all servers with their own key together, so free servers can't take every slot from paying ones 100
STAR_USD What a Star brings in US dollars, for the revenue estimates 0.013

Telegram (hosted backends only)

Setting What it does Default
TELEGRAM_BOT_TOKEN The payment bot's token; without it there are no payment links unset
TELEGRAM_ADMIN_IDS Telegram user ids, comma-separated, that may /refund <charge id> in the bot unset
TELEGRAM_WEBHOOK_SECRET The webhook's secret token derived from the bot token
SUPPORT_CONTACT Who to contact for more than the plans give, like @name or an email; the bot shows it under the plans. Since 6.9 unset
TELEGRAM_POLLING Take updates by long polling instead of the webhook, for local runs off
TELEGRAM_API_URL A Bot API server of your own https://api.telegram.org
TELEGRAM_TEST_ENV Talk to Telegram's test environment off

Address

Setting What it does Default
API_URL The backend's public address; the Telegram webhook goes to API_URL/api/telegram/webhook https://allay.chat
PUBLIC_URL Where people reach the backend in a browser, with any path prefix. /allay init links and the panel start here API_URL

Access

Setting What it does Default
PLUGIN_TOKEN Self-hosted: the token every plugin sends as Authorization: Bearer (server.token in its config.yml), at least 24 characters. Without it the backend answers no plugin unset
TRUSTED_PROXIES Addresses and CIDR ranges of the reverse proxies in front of the backend, comma-separated; only their forwarding headers count unset: nobody
CLIENT_IP_HEADER The header a trusted proxy puts the client's address in: x-forwarded-for, x-real-ip, or cf-connecting-ip x-forwarded-for

Next: Who pays for the model

Clone this wiki locally