Metering & capacity

Usage, queryable by your labels

Every sandbox accrues per-second spans tagged with the labels you set at create. The usage API is the invoice. Nothing to reconcile, nothing to estimate.

u = nc.usage.query(label="trial_id:tr_8bd2")
u["spans"]
# [{"kind": "compute", "vcpu": 4, "mem_gib": 8, "seconds": 877,
#   "cost_usd": 0.058, "billable": true, ...}]
u["total_cost_usd"]
u["unbilled_provider_fault_usd"]   # provider_* seconds, credited
  • compute spans bill vCPU + memory per second while running.
  • suspended spans bill captured state at the storage rate.
  • Spans whose sandbox ended with a provider_* cause carry billable: false. We report them and never charge them.

Capacity is visible, and reservable

Before a large fan-out, ask what is free, or hold it. A create that exceeds free capacity fails fast with a typed 409 (provider_capacity) instead of a silent retry loop.

nc.capacity.get()
# {"vcpu_free": 3200, "mem_gib_free": 12800, ...}

nc.capacity.reserve(vcpu=4, mem_gib=8, count=500,
                    duration_minutes=120,
                    labels={"sweep": "nightly"})
# 500 sandboxes guaranteed for the next two hours

Webhooks

We deliver state-change events (running,exported, terminated with cause) to your endpoint. Polling is optional.