Pre-release. HareBox is a working local build with no public service yet. Statuses on every feature say what runs today; speed and reliability figures are targets until measured. Status

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

  1. 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-v1

    Python

    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 } });
  2. Create a sandbox when a customer signs up

    Label it with the customer's ID so usage, budgets and webhooks can follow it. --no-env keeps 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 });
  3. 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 month

    Python

    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" } });
  4. 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 Preview

    Python

    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 } });
  5. 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 2

    Python

    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);
    }
  6. 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);
  7. 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 --json

    Python

    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 upgrade or 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.