Agent platforms, a sandbox per customer
Give every user or project of your product its own persistent computer, agent and preview URL, and bill them for exactly what they use.
For Founders building Devin-style or Lovable-style products
Why it pays
- A computer per customer, without a fleet to run No hypervisors, networking, snapshots or desktop streaming to build. Each customer gets real isolation from their own kernel.
- Costs follow usage Stop a sandbox when the user leaves and resume it when they return. A stopped sandbox costs nothing for 14 days.
- Margin you can measure Read exactly what each sandbox cost, per period, and bill your customer with your own markup.
Step by step
Build one golden environment
Install your stack and agent once, then save it as a versioned template. Every new customer starts from it in one call.
CLI
harebox new --name golden --size default harebox exec current -- ./install-stack.sh harebox template save current --name app-v1Python
from harebox import HareBox hb = HareBox() golden = hb.create(name="golden", size={"preset": "default"}) golden.run("./install-stack.sh") hb.create_template(body={"name": "app-v1", "sandbox": golden.id})TypeScript
import { HareBox } from "@harebox/sdk"; const hb = new HareBox(); const golden = await hb.create({ name: "golden", size: { preset: "default" } }); await golden.run("./install-stack.sh"); await hb.createTemplate({ body: { name: "app-v1", sandbox: golden.id } });Create a sandbox when a customer signs up
Label it with the customer's ID so usage, budgets and webhooks can follow it.
--no-envkeeps your own secrets out of a machine your customer controls.CLI
ACME=$(harebox new --from app-v1 --name cust-acme --label customer=acme --no-env | jq -r .id)Python
box = hb.create(template="app-v1", name="cust-acme", labels={"customer": "acme"}, no_env=True)TypeScript
const box = await hb.create({ template: "app-v1", name: "cust-acme", labels: { customer: "acme" }, no_env: true });Cap what each customer can spend
A budget on the customer's label stops their sandboxes when the limit is reached, so one runaway agent can't eat your margin.
CLI
harebox budget new --limit 50 --scope label:customer=acme --action stop --period monthPython
hb.create_budget(body={"limit_usd": 50, "scope": "label:customer=acme", "action": "stop", "period": "month"})TypeScript
await hb.createBudget({ body: { limit_usd: 50, scope: "label:customer=acme", action: "stop", period: "month" } });Give the customer a live preview
Expose the app's port at a private HTTPS URL that wakes the sandbox on the first request.
CLI
harebox host "$ACME" 3000 --title PreviewPython
url = hb.create_endpoint(box.id, body={"port": 3000, "title": "Preview", "wake_on_request": True})["url"]TypeScript
const { url } = await hb.createEndpoint(box.id, { body: { port: 3000, title: "Preview", wake_on_request: true } });Run the agent on the customer's request
Send the request to a harness inside their sandbox and stream the result back to your UI.
CLI
harebox prompt "$ACME" "Add a pricing page with three plans" --harness claude --budget 2Python
for event in box.prompt("Add a pricing page with three plans", harness="claude", budget_usd=2): send_to_browser(event)TypeScript
for await (const ev of box.prompt("Add a pricing page with three plans", { harness: "claude", budget_usd: 2 })) { sendToBrowser(ev); }Stop when they leave, resume when they return
Files, packages and enabled services survive a stop. Resume on their next message.
CLI
harebox stop "$ACME" harebox resume "$ACME"Python
box.stop() box.resume()TypeScript
await hb.stopSandbox(box.id); await hb.resumeSandbox(box.id);Bill each customer from the meter
Group a month's usage by customer label and turn it into invoices, with your own price on top.
CLI
harebox usage --all --group-by label --jsonPython
report = hb.get_usage(query={"group_by": "label", "since": "2026-11-01"}) for group in report["groups"]: invoice(group)TypeScript
const report = await hb.getUsage({ query: { group_by: "label", since: "2026-11-01" } }); for (const group of report.groups) invoice(group);
Tips
- Tie deletion to an explicit “delete my project” action, never to an idle timer. Delete can't be undone.
- Publish production builds to a CDN, so real traffic doesn't depend on a sandbox being awake.
- Save a template version for each release of your stack, and move customers forward with
harebox env upgradeor a new template. - Stopped disks are free for 14 days, then move to paid cold storage instead of being deleted, so a returning customer never loses work.
Related use cases
Parallel agent fleets
Prepare one environment, fork it into many exact copies, and give each copy its own task. Keep the winner, delete the rest.
See the stepsA coding agent on your repository, with a spending cap
Hand an issue to Claude Code, Codex or OpenCode in a clean VM, follow it live, cap what it can spend, and get a pull request back.
See the stepsBrowser automation and scraping at scale
Run real Chrome with persistent profiles on a real desktop, record sessions for audit, and fork a logged-in browser into many.
See the steps

