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, creditedprovider_* cause carry billable: false. We report them and never charge them.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 hoursWe deliver state-change events (running,exported, terminated with cause) to your endpoint. Polling is optional.