Muse AI docs
v2.0.0
Live demoConsole demo Get help
● Set up · One section per console page

Operator console.
Every page, what it changes.

The console is where you run Muse AI: keys, models, modules, plans, limits, money, users, reports and push. It is the MIKODES Admin Kit served by admin/ at /admin. You use it in a browser like any website; nothing here needs code. Every screenshot is a real capture of the 2.0.0 console with its built-in sample data (ADMIN_DATA=sample), where some money switches are on so their screens show; a fresh install has them off.

Saves write config/public + config/privateHistory and rollbackAudit logRoles: owner, manager, viewer

01Signing in, roles and saving

Think of the console as the control panel of your app. You change a value, click Save changes, and the app picks it up the next time a user opens it.

  • First owner: created with the one-time setup code from the log (Installation, step 3).
  • Roles: viewers read; managers change settings and act on the product pages; only the owner sets secrets (keys) and store identifiers and manages the team.
  • Saving: edits collect in a bar at the bottom ("4 unsaved changes in Brand") with Discard and Save changes. Each save becomes a version in History and an entry in the Audit log, and the console writes config/public and config/private to Firestore at once. The app picks the change up the next time it starts (the API caches the config for 60 s).
  • Search: the box at the top (or ⌘K / Ctrl K) finds any setting, section or action.
  • Limits are enforced by the server: every number has a hard minimum and maximum; out-of-range values are refused.
  • Public demo console: the author's demo at museai-demo.mikodes.com/admin is read-only (account demo@museai.demo, password muse-demo-ae93e3, also shown on its sign-in screen) and runs on sample data.

02Overview

Measured counters only, from the backend's daily statistics (stats/{day}): new and active users, chat messages, input and output tokens as the providers reported them, chat and image failures, images, image edits and tools, natural-voice characters, transcription minutes, AI video seconds, prompts blocked, users on a plan, open reports. Nothing is extrapolated. Also: net revenue of the last 30 days, a "Needs you" list and a configuration health score.

Console Overview with today net, events, blockers and health strip, users on a plan and open reports tiles marked demo, net revenue with no source connected, Needs you and Configuration health
Overview · sample data, tiles marked demo

03Get started

The few fields the product needs before it goes live (product name, accent colour, support e-mail, terms and privacy URLs) and the current blockers, on one page. Each field links to its full section.

Get started page with product name, accent colour, support email and terms URL fields and a progress bar
Get started · sample data

04Brand

Product name (shown in the app and the console header), Tagline, Accent colour (buttons, highlights and gradients in the app) and Support email (Settings → Contact support). Never use a third-party trademark as the product name. Before and after pictures: Customization.

06Features

Switch whole parts of the app on or off; a switched-off feature disappears from the app. Core: AI chat, Image generator, Voice input and read-aloud, Chat about photos, Chat about PDF and text files, Assistants, Prompt library, Web search, Cloud backup, Share and export. Studio: Discover, Voice mode, Natural voices, Transcription, Video editor, Auto captions, AI video generation, AI image editing, Image tools, Incognito chats, Suggested follow-up questions. A module that calls a paid provider stays hidden while its provider has no key, whatever the switch says.

Features section with toggles for AI chat, image generator, voice input, photos, PDF and assistants
Features · read-only demo console

07Sign-in methods

Which sign-in buttons the app shows: Continue with Google, Continue with Apple (iOS and web), E-mail and password. Turn a method on only after enabling the same provider in Firebase Authentication; Google on Android also needs the SHA-1 and SHA-256 of your signing key in Firebase, and on iOS the REVERSED_CLIENT_ID URL scheme in Info.plist (Release → iOS sign-in). Apple's guideline 4.8: keep Apple on if Google is on. Sign-in is optional; cloud backup needs a signed-in account.

Sign-in methods section with Continue with Google, Continue with Apple and E-mail and password switched on
Sign-in methods · defaults

08Chat

Default model id (empty = the first enabled free model), Model for chat titles and prompt enhance (free for the user; empty = the cheapest enabled model), Messages sent as context (2–100, default 30), Allow web search (needs the feature and a model that supports it; searches are billed by the provider), Suggest follow-up questions after an answer (up to 3, at most 200 per user and day) and Suggestions on the empty chat (up to 8, each up to 80 characters).

Chat section with default model id, title model, messages sent as context, allow web search off and follow-up suggestions on
Chat · sample settings

09AI providers & keys

Anthropic, OpenAI (plus an optional base URL for a proxy), Google Gemini and four OpenAI-compatible endpoints (name, base URL, key), and the global daily AI call cap. Keys are write-only: after saving they are never shown again, only "Set · updated …" with Replace, Clear and Test connection. Details and every tester message: AI providers and models; where to get each key: Provider dashboards.

AI providers and keys section with Anthropic, OpenAI and Gemini keys not set and the OpenAI base URL field
AI providers & keys · no key set

10Image providers & keys

OpenAI key for images, Google key for Imagen (both fall back to the AI provider keys when empty), fal.ai key, Stability AI key, and the global daily image cap (image edits and tools count toward it). Each test makes one request that generates and bills no image.

Image providers and keys section with OpenAI, Google Imagen, fal.ai and Stability AI keys not set
Image providers & keys

11Chat models

The list editor of the chat catalog: id, label in the app, provider (and compatible endpoint), provider model id, tier (free or a plan id), credit cost per message (0–1000), max output tokens (256–32000), badge, your price per 1M input and output tokens, capabilities (photos, PDF files, web search, reasoning, fast) and Enabled. Click a row to edit it, Apply to the list, then Save. Status column: Needs a key (its provider has no key: written to the app as disabled), Live or Off. At most 50 models.

Chat models list with Muse Fast, Muse Pro and Muse Max, status Needs a key, provider Anthropic, tiers Free and Pro rank 1, credits and capabilities
Chat models · before any key is set

12Image models & styles

Two tabs. Image models: provider, model id, tier, credits per image and your price per image. Styles: the 12 presets of the Image Studio, each a label, a prompt suffix added to the user's prompt and the preview tile it uses; a style can be hidden. At most 20 image models.

Image models tab with Muse Image on OpenAI gpt-image-1 and Muse Flash on fal.ai flux schnell, both marked Needs a key
Image models · read-only demo console

13Image tools

A page and a settings section. The page lists the image edit models (two ship, disabled: "Muse Edit" on OpenAI gpt-image-1 and "Muse Restyle" on a fal.ai Kontext model). The settings hold the fal.ai model ids of Remove background and Upscale (empty = hidden) and your price per call. Guide: Image tools.

Image tools page with the one-tap tool model ids and two image edit models marked Needs a key
Image tools · read-only demo console

14Voices & transcription

A page and a settings section. The page lists the natural voices the app offers (six OpenAI voices ship, disabled), each with provider, provider voice, model, tier and your price per 1M characters. The settings hold the OpenAI, ElevenLabs, Gemini and Deepgram keys (each with a tester), the transcription provider and model, the two global daily caps and your price per transcription minute. Guide: Voice.

Voices and transcription page with six OpenAI voices Nova, Alloy, Echo, Shimmer, Onyx and Sage marked Needs a key
Voices & transcription · read-only demo console

15Video

A page and a settings section. The page lists the AI video models (two fal.ai Kling models ship, disabled): provider, model id, durations, aspect ratios, image-to-video, credits per second, tier and your price per second. The settings hold the fal.ai and Replicate keys and the daily job cap. Guide: Video Studio.

Video page with Muse Motion and Muse Motion Photo on fal.ai Kling models, durations 5 and 10 seconds, aspects and tier Pro rank 1
Video · read-only demo console

16Caption styles

The presets of the auto-caption editor, with a live preview: font family, size, colours, outline, background box, position, word or karaoke highlight, upper case, words per line, tier and shown or hidden. Eight ship: Classic, Bold Pop, Karaoke, Minimal, Neon, Boxed, Subtle, Headline. At most 30.

Caption styles page with previews of Classic, Bold Pop, Karaoke and Minimal and their font, position and highlight
Caption styles · read-only demo console

17Discover

A page and a settings section. The page edits the categories (up to 12) and the RSS / Atom feed sources (up to 50, stored only in config/private), each with Test feed, which fetches the feed from the server and shows its first three titles. The settings switch Discover on, the "For you" tab, who gets AI briefs, the refresh interval and how long items are kept. Guide and publisher terms: Discover.

Discover settings with Offer Discover, Show a For you tab, Who gets AI briefs, refresh interval and item age
Discover settings · read-only demo console (Discover on for the demo)

18Assistants

The ready-made assistants (24 ship): name, emoji, category, description, instructions (the system prompt), up to 4 conversation starters, an optional fixed model and the tier.

Assistants list editor with emoji, name, category, description, model, tier and active columns
Assistants · the shipped defaults

19Prompt library

Prompt templates users pick in Assistants and prompts (30 ship). Words in {curly braces} become fields the user fills in, for example "Write a polite follow-up email to {name} about {topic}." At most 200.

Prompt library list with titles, categories and template texts with placeholders
Prompt library · the shipped defaults

20Catalogs (raw)

Every catalog (chat models, image models, styles, assistants, prompts, plans, Discover categories and feeds, voices, video models, image edit models, caption styles) as one JSON object per line, for bulk edits or copy and paste between installs. Both editors save to the same settings with history and audit. An invalid line is skipped and named on Status.

Catalogs (raw) section with the chat models, image models and image styles as one JSON object per line
Catalogs (raw) · the shipped defaults

21Moderation

Moderation endpoint: None (blocklist and provider safety only) or OpenAI moderation (omni-moderation-latest, uses the OpenAI key). Blocked words: up to 500 words or short phrases, matched as whole words, case-insensitive. What is checked and what is not: Security → moderation scope. A failing moderation endpoint does not block. The text of blocked prompts is never stored; only the count.

Moderation section with the moderation endpoint select and an empty blocked words list
Moderation · defaults

22Limits

What a user without a plan gets, enforced by the server: per UTC day chat messages (20), images (2), image edits and tools (2), natural-voice characters (3,000), transcription minutes (5), Discover briefs (5) and rewarded unlocks (3); per month AI video seconds (0 = only with a plan) and auto-caption minutes (3). Each plan's own limits are on the Plans page. Credits come on top.

Limits section with free chat messages, images, image edits and tools, AI video seconds per month and auto-caption minutes per month
Limits · defaults

23Plans

Up to 4 subscription plans: id, name, tagline, rank, highlight, colour, store product ids per period for Android and iOS, trial days shown, features with icons, every limit, no ads, active. There is no price field: the app shows the stores' prices. Guide: Plans and paywall.

Plans page with one plan Pro, rank 1, highlighted, sold monthly and yearly, 500 messages and 50 images per day, no ads
Plans · the sample plan, offered in the demo

24Paywall

Layout (cards or list), the period selected first, when the paywall shows (first launch, every n launches, when a free limit is reached), the delay before the close button (at most 5 seconds), the title, subtitle and the line under the buttons.

Paywall section with layout, period selected first, show on first launch and every n launches
Paywall · read-only demo console

25Store & purchases

The master switch Sell in-app purchases, the Remove-ads and credit-pack product ids, the credits in each pack, and the store verification credentials (owner only): Android package name, Google Play service account JSON, iOS bundle id, App Store Connect issuer id, in-app purchase key id and .p8 key, App Store environment. See In-app purchases.

Store and purchases section with Sell in-app purchases on, remove-ads product id and credit pack product ids
Store & purchases · sample settings (on); a fresh install has it off

26Ads and the network id pages

Ads: the master switch, one network or a waterfall per format, AdMob server-side verification for rewarded ads, and every placement. AdMob ids, Unity Ads ids, ironSource LevelPlay ids: the app and unit ids from each network's dashboard. See Ads.

Ads section with Show ads on, fill mode, network select and waterfall lists per format
Ads · sample settings (on, no unit ids); a fresh install has ads off
AdMob ids section with Android and iOS app id and banner and interstitial unit fields, all empty
AdMob ids · empty
Unity Ads ids section with Android and iOS game id and unit fields, all empty
Unity Ads ids · empty
ironSource LevelPlay ids section with Android and iOS app key and unit fields, all empty
ironSource LevelPlay ids · empty

27Ad revenue reporting

Optional credentials so the Revenue centre can pull finished days from AdMob: AdMob publisher id and AdMob API OAuth client id, secret and refresh token (scope admob.readonly). Unity Ads and LevelPlay income is recorded by hand with a reference. Not connected = ad revenue "not measured"; nothing is estimated.

Ad revenue reporting section with AdMob publisher id and AdMob API OAuth client id, secret and refresh token
Ad revenue reporting · not connected

28Revenue centre

Realised revenue only, per kind, source and currency (never converted): verified store purchases written by the backend, plus ad payouts or other income you record with a required, unique reference. With AdMob reporting connected, pull one finished day (repeating a pull does not double count).

Revenue centre with period tabs and the message that the sample shows no revenue at all
Revenue centre · the sample shows no revenue on purpose

29Users

Most users are anonymous, so there are no names or e-mails: search by user id. Grant a plan until a date or for life, revoke a console grant (a store purchase is never touched), add or remove bonus credits (up to ±10,000 per change, never below 0), grant Remove ads, ban or unban. Every action needs a reason and is in the audit log. Conversations are never shown here.

Users table with sample user ids, platform, joined, last seen, plan, bonus and purchased credits and status columns
Users · sample users, ids start with sample-

30Reports

The review queue of what users reported with the report button under answers and images: reason, note, prompt, the reported answer, and the image on request (a 15-minute signed link, logged). Mark each one reviewed or actioned with what you did. This is the only conversation text the console ever shows. App stores expect you to review reports of AI content.

Reports queue with open sample reports showing reason, model, user id, note, prompt and reported answer
Reports · sample reports with sample text

31Push campaigns

Title (up to 65 characters), message (up to 240), segment (everyone, users on a plan, or free users), an optional assistant to open, and a send time in UTC or Send now. Cancel while scheduled. The backend's sendCampaigns job sends due campaigns every 5 minutes; the console never sends itself.

Push campaigns with three sample campaigns and the new campaign form
Push campaigns · sample campaigns, nothing is sent

32Usage & spend

Calls, tokens and images per model for 7, 30 or 90 days, and a second table for natural-voice characters, transcription minutes, AI video seconds, image edits and tool calls, with today against the daily caps. Spend is computed from usage × the prices you entered and labelled so; an item without a price shows "—". It is not your provider's invoice.

Usage and spend page in sample mode showing not measured for messages, tokens, images, voice characters, transcription minutes and video seconds
Usage & spend · nothing measured in sample mode

33Status

Health checks: Firestore reachable, app config written, at least one chat model enabled with a key, each provider key valid (a passing test is reused for an hour), compatible endpoints, image keys, today's calls and images against the caps, moderation, ad ids for what is switched on, store verification, ad reporting, legal URLs; for the studio modules also plans sellable, image edit and tool keys, voice keys, video keys and "Discover feeds healthy". Blockers stop a launch; warnings are worth a look.

Status page listing checks with warning, info and not measured badges in sample mode
Status · sample mode, Firebase checks not measured

34Audit log and History

Audit log: who changed what, when and why, with a readable diff; filter by actor, action, setting and date; export CSV. It cannot be edited, and secrets appear only as "set" or "cleared". History: every save is a version; compare two versions or Roll back (which creates a new version, so nothing is lost). A stale editor is refused instead of overwriting someone else's save.

Audit log with entries for a failed Anthropic key test, the key being set, suggestion and brand changes and owner creation
Audit log · after the customization example
History page with saved versions and Roll back buttons
History

35Team, Security & alerts, Notifications, Export / Import

  • Team: add members by e-mail as viewer, manager or owner.
  • Security & alerts: your two-factor (authenticator app), where you are signed in (sign out everywhere), the team rule "Require two-factor for owners and managers", and alert rules.
  • Notifications: the alert webhook URL and its signing secret. Alerts are JSON signed with HMAC-SHA256 in the x-mikodes-signature header; no e-mail is sent. Payload and a verification example: Alert webhook.
  • Export / Import: download every setting as JSON (never secrets) or upload one; you see exactly what changes before anything is applied. Owner only.
Team page with the owner and an Add a member form with e-mail and role
Team
Security and alerts page with two-factor off, the current session, the team two-factor rule and alerts
Security & alerts
Export and import page with Download JSON and Choose file
Export / Import

36Alert webhook: payload and signature

When an alert rule fires (Security & alerts: "a blocker starts failing" or "no net revenue for n days"), or when you press Send test alert, the console sends one POST to the Webhook URL from Console → Notifications. Redirects are not followed, and every attempt is written to the audit log.

Request

POST /your-endpoint HTTP/1.1
content-type: application/json
user-agent: mikodes-admin-kit
x-mikodes-event: test
x-mikodes-timestamp: 1762700000
x-mikodes-signature: sha256=<64 hex characters>

{"type":"mikodes.alert.test","product":"museai","productName":"Muse AI","at":"2026-11-09T14:53:20.000Z","title":"Test alert","detail":"A test alert from the Muse AI console, sent by owner@example.com."}
FieldTypeMeaning
typestringmikodes.alert.test, mikodes.alert.blocker or mikodes.alert.revenue (the same value as x-mikodes-event, with the prefix)
product, productNamestringmuseai and the product name
atstring (ISO 8601, UTC)When the console sent it
titlestringOne line, for example "Blocker failing: App config written to Firestore"
detailstringThe explanation; several lines for a blocker alert (one per failing check)

How the signature is made

x-mikodes-signature is sha256= followed by the lowercase hex HMAC-SHA256 of the string <x-mikodes-timestamp>.<raw request body>, keyed with the Webhook signing secret. The timestamp is Unix seconds. Compute it over the raw body exactly as received, before any JSON parsing.

Verify it (Node.js, no dependencies)

Save as verify-alert.mjs, then run WEBHOOK_SECRET='your signing secret' node verify-alert.mjs and set http://<your-host>:8099/ (behind HTTPS in production) as the Webhook URL.

import { createServer } from "node:http";
import { createHmac, timingSafeEqual } from "node:crypto";

const SECRET = process.env.WEBHOOK_SECRET ?? "";
const MAX_AGE_SECONDS = 300; // refuse old or replayed alerts

function verifyAlert(secret, timestamp, rawBody, signatureHeader) {
  if (!secret || !timestamp || !signatureHeader?.startsWith("sha256=")) return false;
  const age = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (!Number.isFinite(age) || age > MAX_AGE_SECONDS) return false;
  const expected = createHmac("sha256", secret).update(`${timestamp}.${rawBody}`, "utf8").digest("hex");
  const got = signatureHeader.slice("sha256=".length);
  return got.length === expected.length && timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}

createServer((req, res) => {
  let raw = "";
  req.on("data", (chunk) => (raw += chunk));
  req.on("end", () => {
    if (!verifyAlert(SECRET, req.headers["x-mikodes-timestamp"], raw, req.headers["x-mikodes-signature"])) {
      res.writeHead(401).end("bad signature");
      return;
    }
    const alert = JSON.parse(raw);
    console.log(`[${alert.type}] ${alert.title}\n${alert.detail}`);
    res.writeHead(204).end();
  });
}).listen(8099, () => console.log("Listening on http://localhost:8099"));

Then Console → Security & alerts → Send test alert: the script prints [mikodes.alert.test] Test alert, and the console shows "HTTP 204 from <your host>". A wrong secret gives "HTTP 401". The console counts any 2xx answer as delivered.

Check the snippet without the console

This signs a sample body the same way the console does and sends it to the script above:

SECRET='your signing secret'
BODY='{"type":"mikodes.alert.test","product":"museai","productName":"Muse AI","at":"2026-11-09T14:53:20.000Z","title":"Test alert","detail":"Manual test"}'
TS=$(date +%s)
SIG=$(printf '%s' "$TS.$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')
curl -i -X POST http://localhost:8099/ -H 'content-type: application/json' \
  -H "x-mikodes-timestamp: $TS" -H "x-mikodes-signature: sha256=$SIG" --data "$BODY"

Terminal: macOS or Linux as shown; on Windows use WSL or Git Bash (how).

37What the console never does

  • It never reads a conversation, calls an AI model for a user or sends a push message itself.
  • It never writes the backend's fields (the store plan, purchased credits, usage, statistics, images, videos, purchases, store revenue events).
  • It never shows a stored key again and never puts one in config/public.
  • It never estimates revenue or converts currencies.