> ## Documentation Index
> Fetch the complete documentation index at: https://docs.boat.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Billing & Limits

> How Boat billing works: per-second pricing, plans, credits, what is included, and what happens when you run out.

Boat bills machine time by the second, only while a sandbox is running.

* **\$1 buys 100,000 seconds** of machine time, about 27 hours. That is \$0.036 per hour, or about \$26 for a `default` sandbox running 24/7 for a month.
* **Stopped sandboxes are free.** Stopping snapshots the filesystem and pauses billing until you resume.
* **Size changes the rate.** A `small` sandbox consumes machine time at 0.5x, so the same balance lasts twice as long; a `large` sandbox consumes it at 2x, and an `xlarge` sandbox costs \$0.20 per running hour. See [Machine Capabilities](/machines) for what each size gives you.

| Type      | Machine time            | Effective cost                       |
| --------- | ----------------------- | ------------------------------------ |
| `small`   | 0.5 seconds per second  | \$0.018/h, \~\$13/month running 24/7 |
| `default` | 1 second per second     | \$0.036/h, \~\$26/month running 24/7 |
| `large`   | 2 seconds per second    | \$0.072/h, \~\$52/month running 24/7 |
| `xlarge`  | 50/9 seconds per second | \$0.20/h, \~\$144/month running 24/7 |

Your balance is a single pool of machine time; the type only changes how fast it drains. `boat limits` reports remaining compute in hours and remaining credits in dollars; `boat limits --json` keeps the canonical second counts plus `creditBalanceHours` and `packBalanceDollars`.

`xlarge` requires the effective \$100 monthly plan or higher and a bare-metal allocation from an
Ascii operator. Team seat count does not change this threshold. Gifted \$100-or-higher plans and
service accounts qualify.

## Included with every sandbox

* A dedicated IPv6 or IPv4 address
* Snapshots (the latest snapshot per sandbox is kept, up to your sandbox type's [data size](/machines#machine-types))
* Egress, up to 2 TB per sandbox per month
* Desktop streaming and hosted HTTPS ports

## Plans

Every plan converts its price into machine time at the same rate, and sets your concurrency and start limits:

| Plan      | Included time              | Concurrent sandboxes | Starts / min | Starts / hour | Starts / day |
| --------- | -------------------------- | -------------------- | ------------ | ------------- | ------------ |
| \$20/mo   | 2,000,000 s (\~555 h)      | 100                  | 12           | 60            | 200          |
| \$100/mo  | 10,000,000 s (\~2,777 h)   | 300                  | 30           | 210           | 840          |
| \$500/mo  | 50,000,000 s (\~13,888 h)  | 1000                 | 65           | 420           | 1680         |
| \$2000/mo | 200,000,000 s (\~55,555 h) | 2000                 | 90           | 600           | 2400         |

Upgrade any time from [Dashboard > Billing](https://boat.dev/dashboard?tab=billing). Need more than the largest plan? Contact us, higher limits are agreed case by case.

### On the free trial

Every plan starts with a free 7-day trial. Until your first payment lands, an account runs under its own limits rather than the plan's:

| Limit                  | On trial                                        |
| ---------------------- | ----------------------------------------------- |
| Concurrent sandboxes   | 2                                               |
| Machine starts         | 5 / min, 25 / hour, 75 / day                    |
| Machine time, in total | 25 hours                                        |
| Auto-stop              | required, 2 hours maximum                       |
| Machine size           | `small` and `default`; `large` is not available |

Two of these change how sandboxes behave rather than how many you get. `--no-auto-stop` and any `--ttl` above two hours are refused with `trial_auto_stop_required`, and a resumed trial sandbox gets a fresh window capped the same way, so nothing you start on the trial can run unattended overnight. `--type large` is refused with `trial_machine_class_not_allowed`. Adding a payment method lifts all five at once.

### Machine starts

Creating a sandbox, forking one and resuming a stopped one each count as one **machine start**, so a platform that stops sandboxes aggressively spends the same budget as one that creates them.

Each plan sets three start limits, all listed above: a per-minute burst rate, and hour and day ceilings that bound sustained spawning. Size the per-minute rate for your spikiest moment, the hourly ceiling for your busiest hour, and the daily ceiling for your total traffic. `GET /limits` (and `boat limits --json`) reports `starts.minute|hour|day` with `limit`, `used` and `remaining` for the rolling windows. Past any of them the API answers `429` with `rate_limited`, names which window you hit, and includes the same `starts` remaining counts. These limits scale with your plan and rise as we add capacity, and committed accounts can have them lifted further, so contact us if you need more.

## Plan time vs credit packs

Your two pools work differently, and the difference only shows up at renewal:

* **Plan time** is granted fresh at the start of every billing month and expires at the end of it. Whatever you did not spend is **not** carried forward and is not converted into credits.
* **Credit packs** (\$20 buys 2,000,000 seconds) never expire and carry over month to month.

**Plan time is always spent first.** Credits are only drawn once a month's plan time is exhausted, and once drawn they are gone for good. The next renewal restores your plan time but never refills your credits.

So a \$20/month subscriber who also bought one \$20 pack, and used 2.5M seconds in a month, ends that month having spent all 2M seconds of plan time plus 500,000 seconds of credit. They start the next month with 2M fresh plan seconds and 1.5M credit seconds remaining.

Check your balance any time:

<CodeGroup>
  ```bash CLI theme={null}
  boat limits
  boat limits --json
  ```

  ```bash curl theme={null}
  curl -sS "$BOAT_API_BASE/limits" \
    -H "Authorization: Bearer $BOAT_API_KEY"
  ```

  ```ts TypeScript theme={null}
  const limits = await sandbox.limits();
  console.log(limits.canStart, limits.starts?.day?.remaining, limits.creditBalanceHours, limits.packBalanceDollars);
  ```

  ```python Python theme={null}
  limits = sandbox.limits()
  day = getattr(limits.starts, "day", None)
  print(limits.can_start, getattr(day, "remaining", None), limits.credit_balance_hours, limits.pack_balance_dollars)
  ```
</CodeGroup>

See [Get Boat limits](/api/reference/account/get-boat-limits) for every field.

## Per-sandbox usage

Every sandbox meters its own machine time, so a platform that gives each of its users or agents a sandbox can bill them from the same numbers your balance drains by. Read one sandbox at any time, running or stopped:

<CodeGroup>
  ```bash CLI theme={null}
  boat usage bx_23456789
  boat usage bx_23456789 --since 2026-09-01 --until 2026-10-01
  boat usage bx_23456789 --json
  ```

  ```bash curl theme={null}
  curl -sS "$BOAT_API_BASE/sandboxes/bx_23456789/usage?since=2026-09-01T00:00:00Z&until=2026-10-01T00:00:00Z" \
    -H "Authorization: Bearer $BOAT_API_KEY"
  ```

  ```ts TypeScript theme={null}
  const usage = await sandbox.usage({ sandboxId: "bx_23456789", since: "2026-09-01T00:00:00Z", until: "2026-10-01T00:00:00Z" });
  console.log(usage.seconds, usage.dollars, usage.running);
  ```

  ```python Python theme={null}
  usage = sandbox.usage("bx_23456789", since="2026-09-01T00:00:00Z", until="2026-10-01T00:00:00Z")
  print(usage.seconds, usage.dollars, usage.running)
  ```
</CodeGroup>

`seconds` is billable machine time with the sandbox type's multiplier already applied, so a `large` sandbox that ran ten minutes reads 1200, and `dollars` is that at list price (`seconds / secondsPerDollar`). Stopped time is never counted, time past a [refused stop](/snapshots#when-a-stop-is-refused) is excluded, and a running sandbox keeps growing until it stops, which `running` tells you (`false` also while a refused stop holds the meter paused). Omit `since` and `until` for the sandbox's whole life; a billing period boundary that falls inside a running stretch splits it pro rata. See [Get boat usage](/api/reference/sandboxes/get-sandbox-usage) for every field.

## Organizations

An organization has one shared balance and one plan, and any member can run sandboxes against it. Which balance a sandbox draws from is decided when the sandbox is created and travels with it from then on. The organization is a **wallet**, not a shared workspace: sandboxes, snapshots, and environments stay with their creator.

### How limits apply on an organization

The start-rate and concurrency numbers on the plan are **one shared pool for the whole organization**, not a private allowance per member.

A 5-seat organization on the \$20 plan has the \$20 ceilings × 5: 500 concurrent sandboxes, 60 starts/min, 300/hour, 1000/day. Those counters key on the organization's wallet. If one member burns the hourly start budget, every other member's `boat new` / `fork` / `resume` billed to that organization is refused until the window rolls. A member's personal sandboxes use that member's own personal limits and do not count against the organization pool.

Those shared ceilings only stay seat-scaled while the organization's Stripe subscription is active. If the plan is canceled, leftover credit packs can still run sandboxes, but concurrency and start rate drop to a single seat.

On top of the shared pool, the owner can cap an individual member (see [Per-member caps](#per-member-caps)).

Pick the scope once and it sticks for every later `boat new`:

```bash theme={null}
boat org                     # the wallet in effect right now
boat org list                # organizations you belong to
boat org switch acme         # bill new sandboxes (and limits) to acme
boat org switch personal     # back to your own account
boat --org acme new          # bill one create to acme without switching
```

The dashboard org selector bills the selected org the same way: create sends `org` in the body (and `X-Boat-Org`). `GET /limits` accepts `?teamId=`, `?org=`, or `X-Boat-Org` for the remaining starts and balance.

|                                | CLI                                       | API                                      | SDKs          | Dashboard                                                                   |
| ------------------------------ | ----------------------------------------- | ---------------------------------------- | ------------- | --------------------------------------------------------------------------- |
| See your organizations         | `boat org list`                           | not available                            | not available | [Organization](https://boat.dev/dashboard?tab=org)                          |
| Choose the billing scope       | `boat org switch` / `--org`               | `?org=` / `X-Boat-Org` (wallet only)     | not available | sidebar org selector                                                        |
| Bill one sandbox to an org     | `boat --org acme new`                     | `POST /sandboxes` with `org` or `teamId` | not available | [Sandboxes](https://boat.dev/dashboard?tab=sandboxes) with the org selected |
| Create / transfer / delete org | `boat org create` / `transfer` / `delete` | team routes                              | not available | [Organization](https://boat.dev/dashboard?tab=org)                          |
| Invite and remove members      | not available                             | not available                            | not available | [Organization](https://boat.dev/dashboard?tab=org)                          |
| Per-member usage and caps      | not available                             | not available                            | not available | [Organization](https://boat.dev/dashboard?tab=org)                          |

<Note>
  Invites, member-role changes, and per-member caps stay in the dashboard. Listing, snapshots, and environments stay creator-private even when a request carries an org scope. Per-sandbox API keys cannot escape their sandbox or environment grant; out-of-scope targets return `403 api_key_sandbox_forbidden`.
</Note>

### Per-member caps

One shared balance means one member can spend it all. The owner can set two caps per member on the [Organization](https://boat.dev/dashboard?tab=org) tab, both unlimited by default:

| Cap                  | Limits                                                             |
| -------------------- | ------------------------------------------------------------------ |
| Usage cap            | That member's organization-billed machine time per billing window  |
| Concurrent sandboxes | How many organization-billed sandboxes that member can run at once |

Both apply only to organization-billed sandboxes. A member's personal sandboxes are never counted or touched, so a cap of zero means "no spending on this organization", not "no sandboxes at all".

Past a **usage** cap, `boat new`, `boat fork` and `boat resume` on the organization scope answer `402` with `team_member_cap_reached`. Past a **concurrent-sandbox** cap they answer `429` with `member_limit_reached`. The member's organization sandboxes are snapshotted and archived within about a minute. There is no grace period, because a cap is policy rather than a failed payment, and nothing is lost or owed. Raising the cap, or the billing window renewing, makes those sandboxes resumable again.

## Running out

When your balance reaches zero you get a **24 hour grace period**, whether or not auto-pay is on. Your sandboxes keep running and you are alerted by email, so you can top up before anything stops. If the window passes without payment, running sandboxes are stopped with a snapshot. Nothing is lost; resume them after topping up.

To never hit that stop, enable **auto-pay** in the billing dashboard. It charges your saved card in small automatic increments when you run out, drawing from any prepaid balance on your account first.

If a monthly renewal payment fails while you still have credits, your sandboxes stay up until the credits run out.

Because sandboxes keep running through the grace period, you can end up using a little more machine time than you had. `creditBalanceSeconds` stops at zero and reads `0` while that is outstanding; the shortfall is carried and settled on your next payment, so the seconds you consumed are the seconds you pay for.

## Related

* [Build a Platform on Boat](/platform-guide)
* [FAQ](/faq)
* [Long-Running Tasks](/long-running-tasks)
