MintOffice — Technical¶
The technical companion to the MintOffice operator guide. The operator guide walks you through the dashboard wizard; this page is for the developer-facing parts: which repositories you fork, what each one controls, and how a customer's "Buy" click ends up as a running agent on your own domain.
agent-template partner-portal-example Brand Partner API reference
How the pieces fit together¶
A white-label MintOffice setup is three layers, owned by three different people:
┌──────────────────────────┐ ┌──────────────────────────┐ ┌──────────────────────────┐
│ Your storefront │ │ MintOffice (central) │ │ Each customer's agent │
│ (partner-portal-*) │──▶│ mint.mintbot.ai │──▶│ agent1.yourbrand.com │
│ yourbrand.com │ │ + deploy worker │ │ (one VPS per customer) │
└──────────────────────────┘ └──────────────────────────┘ └──────────────────────────┘
you host mintbot hosts mintbot hosts (per agent)
- Storefront — your customer-facing website. Shows plan cards, takes the "Buy" click, forwards the order to MintOffice, receives webhook events. You fork the example, brand it, host it on a domain you control.
- MintOffice central — runs on
mint.mintbot.ai. Owns the Brand Partner API, the Stripe integration, the per-partner secret vault (Telegram bot token, Zone.ee API key, …), the deploy worker, the revenue ledger. Mintbot operates this for every partner; you never run it yourself. - Each customer's agent — a dedicated VPS spun up by the deploy worker
when an order is paid. The persona (SOUL.md), the panel theme, and the
plugin set come from your agent template repo. The customer chats
through your Telegram bot or the web panel on a subdomain of your apex
(
agent1.yourbrand.com).
The two repositories you fork¶
White-label branding sits in two separate repositories, each with a different concern. You fork them independently, on whatever cadence makes sense for your brand.
1. Agent template — what each customer's agent looks like¶
The agent template controls the persona the agent uses, the panel theme (CSS/JS) the customer sees in the browser, and the bundled Hermes plugin set. Every deploy clones a fresh copy from your fork's default branch, so when you push a brand tweak, the next customer who buys gets it; existing agents keep the snapshot they were deployed with.
| Reference repo | mintbot-ai/agent-template — the official, MIT-licensed template, ships with an example brand called ExampleAI so you can see every Jinja variable in context. |
| Live example fork | mintbot-ai/agent99-template — the actual template agent99.cc uses in production. A working reference fork: persona renamed to Agent99, theme palette matched to the storefront. |
| Wired into MintOffice via | Dashboard → Settings → Template → paste your fork's HTTPS URL. The deploy worker calls git clone on every customer deploy. |
| Safety net | Server-side checks on every deploy: persona size cap (48 KB), no chat-template role markers (<\|system\|>, …), no <!-- --> HTML comments. A hostile or broken fork falls back to the bundled persona instead of poisoning a customer's agent. |
The template uses a two-layer model so you can pick the level of effort:
- Voice overlay (
persona/brand_layer.md) — short prose appended to the bundled mintbot persona. Cheap; keeps the rest of the persona on the upstream's update path. - Full override (
persona/system_prompt.md.j2) — replaces the bundled persona entirely. Jinja-rendered withagent_id,panel_domain_base, andbot_handleso you can splice live agent facts into the prompt. Use this when "voice overlay" isn't enough — the Agent99 fork takes this route.
Both files can live side-by-side; render uses the override if present
and otherwise the overlay. The full layout — theme/theme.css,
theme/theme.js, persona/system_prompt.md.j2, persona/brand_layer.md
— is documented in the agent-template README.
2. Storefront portal — what your customer sees before buying¶
The storefront is the website where customers land, browse plans, click Buy, get redirected to Stripe, and come back to a thank-you page. It also receives MintOffice's webhook deliveries so your own systems know when an order is paid, when its agent is ready, when it expires.
| Reference repo | mintbot-ai/partner-portal-example — MIT-licensed FastAPI + SQLite, Dockerised, ships with an ExampleAI brand you swap out. Implements landing, /buy, thank-you/cancel pages, signed webhook receiver, HTTP-Basic-auth /admin event browser. |
| Live example fork | mintbot-ai/partner-portal-agent99 — the actual storefront running on agent99.cc. Same code, brand swapped to Agent99, palette matched to the agent template. |
| Wired into MintOffice via | Dashboard → Settings → API access → set Webhook URL to https://<your-host>/webhooks/mintoffice and copy the signing secret into the portal's .env. |
| You host it | Anywhere with HTTPS — your own VPS, a serverless platform, or alongside one of your customer agents. Mintbot does not host the storefront. |
The example portal is small (a few hundred lines of FastAPI) and the
README walks the rebranding through every touchpoint — .env config,
CSS variables, copy, translations. Start from the live agent99 fork
if you want a closer-to-production baseline; start from the generic
example if you want a clean slate.
End-to-end deploy flow¶
What actually happens when a customer clicks Buy on your storefront:
1. Customer ⟶ POST /buy on your storefront
│
▼
2. Storefront ⟶ POST /api/v1/orders to MintOffice (with your API key)
│ returns checkout_url
▼
3. Customer ⟶ Stripe Checkout (mintbot's Stripe account)
│
▼
4. Stripe webhook ⟶ MintOffice marks order paid
│ fires order.paid webhook to your portal
│ enqueues a deploy job
▼
5. Deploy worker ⟶ spins up a SporeStack VPS
⟶ fetches your agent template repo
⟶ runs apply.py (Hermes config, SOUL.md, plugins, panel)
⟶ provisions DNS A-record via your Zone.ee credentials
⟶ issues Let's Encrypt cert
│
▼
6. agent.ready webhook ⟶ delivered to your portal
⟶ branded handoff email sent (pigeon@mintbot.ai)
⟶ customer can open https://agent1.yourbrand.com
Steps 2 and 4 happen over the Brand Partner API. Steps 5 and 6 are entirely inside MintOffice — your storefront doesn't need to know how SporeStack or Let's Encrypt work; it just receives the lifecycle events.
Brand Partner API¶
The REST surface MintOffice exposes for your storefront (and any other integration of yours) lives on its own page:
Quick mental model:
- Auth —
Authorization: Bearer mo_live_…. One key per partner; rotate from Settings → API access. - Writes are idempotent — every
POSTtakes anIdempotency-Keyheader; retrying with the same key replays the original response. - Reads are cheap —
GET /api/v1/settingsreturns your full non-secret configuration (modes, apex domain, pricing, readiness) for use by your storefront or an installer agent. - Lifecycle is webhook-driven —
order.created,order.paid,agent.ready,agent.failed,agent.expired. HMAC-SHA256 signed, up to 7 retries. - DNS is proxied —
POST /api/v1/dns/recordsupserts an A-record on your apex without your portal ever holding the upstream provider's API key. MintOffice keeps the Zone.ee credential encrypted server-side and makes the upstream call on your behalf.
What MintOffice owns vs. what you own¶
A quick reference for "where does this fact live, and who can change it":
| Fact / asset | Lives in | You can change it via |
|---|---|---|
| Customer plan prices | MintOffice DB | Dashboard → Settings → Pricing |
| Agent persona (SOUL.md) | Your agent template repo | Push to the fork |
| Panel theme (CSS / JS) | Your agent template repo | Push to the fork |
| Storefront copy, layout, plan cards | Your storefront repo | Push and redeploy your portal |
| Customer-facing brand name in emails | MintOffice (driven by product_name per order, with your apex as fallback) |
Set per-order on POST /api/v1/orders |
| Telegram bot token, Zone.ee API key | MintOffice secret vault (encrypted) | Dashboard → Settings → Domain / Bot |
| Stripe API integration | MintOffice (mintbot's Stripe account) | Not partner-configurable |
| Customer's running agent (SOUL.md, config) | The agent's own VPS | The agent itself (after initial seed) |
| Revenue ledger | MintOffice DB | Read-only via GET /api/v1/revenue |
The agent-VPS-first split (last row) matters: once an agent is deployed,
it owns its SOUL.md and config.yaml. Central seeds the VPS once and
steps back — a customer is free to ask their agent to change its
persona, set a BYOK key, switch model — without touching your template
fork or your storefront.
Where to go from here¶
- You're the operator setting up your partner account — start with MintOffice — Overview. It walks the dashboard wizard step by step.
- You're building the integration — start with the
Brand Partner API reference, then clone
partner-portal-exampleas a working baseline. - You're rebranding the agent itself — clone
agent-template(or the Agent99 fork as a closer-to-production starting point), editpersona/andtheme/, push, point the wizard at your fork. - You want to see all of this running —
agent99.ccis a live mintbot.dev partner that uses both example forks end-to-end. Place a test order there to see the same flow you'll be setting up.