Compute units
Compute units meter simulation and sweep work. Every run debits units from your balance; grants (signup, monthly cycle, bounty) add to it. Three read-only endpoints expose the meter:
GET /v1/compute-units/balance— current balance, split by bucket.GET /v1/compute-units/summary— usage against your tier's rolling cap.GET /v1/compute-units/transactions— the full debit/grant ledger.
All three are owner-scoped: they read the calling key's account, take no path parameters, and never mutate.
The wire keeps its original
objectnames (credit_balance,credit_usage_event) andcurrency("credit") for backward compatibility. Only the public field vocabulary moved: a transaction's bucket is reported asunit_type.
Buckets
A balance is split into two non-interchangeable buckets:
| Bucket | Source | Expiry |
|---|---|---|
free | Signup grant; bounty / admin grants | Never expires |
monthly | Monthly billing cycle; beta-trial grant | Expires at the end of the billing period (expires_at) |
The monthly bucket is consumed first — perishable units burn before permanent ones. Once monthly has expired, only free units are usable until the next cycle refills it.
GET /v1/compute-units/balance
Returns a point-in-time snapshot, computed at read time from the live bucket columns.
curl https://thrustlab.com/v1/compute-units/balance \
-H "Authorization: Bearer key_..."Response
{
"object": "credit_balance",
"total": 1234,
"breakdown": [
{"type": "free", "balance": 30, "expires_at": null},
{"type": "monthly", "balance": 1204, "expires_at": "2026-05-25T00:00:00.000Z"}
],
"currency": "credit",
"low_balance_threshold": 200,
"as_of": "2026-04-25T15:42:11.123Z"
}
| Field | Notes |
|---|---|
total | Sum of all usable bucket balances. |
breakdown | One entry per bucket — always free and monthly. Treat the array as open-ended. |
expires_at | null for free; end of the current billing period for monthly. |
currency | Always "credit". |
low_balance_threshold | Balance floor below which a credits.low_balance webhook fires. null for accounts with no recurring grant. |
as_of | ISO-8601 timestamp of the snapshot. |
GET /v1/compute-units/summary
Returns your usage against your tier's cap for the current rolling window — a daily window on free tiers, a weekly window on paid tiers.
curl https://thrustlab.com/v1/compute-units/summary \
-H "Authorization: Bearer key_..."Response
{
"object": "credit_usage_summary",
"tier": "free",
"window": "day",
"used": 12,
"cap": 30,
"remaining": 18,
"resets_at": "2026-04-26T00:00:00.000Z"
}
| Field | Notes |
|---|---|
tier | The resolved account tier. |
window | "day" (free) or "week" (paid). |
used | Units consumed inside the window. A 4-rotor static run counts 4. |
cap | The window cap for your tier. |
remaining | cap - used, floored at 0. |
resets_at | When the oldest in-window debit ages out — the next instant remaining increases. |
GET /v1/compute-units/transactions
Returns your ledger: every debit and grant, newest first, cursor-paginated. Legacy pre-ledger rows are not exposed.
curl "https://thrustlab.com/v1/compute-units/transactions" \
-H "Authorization: Bearer key_..."Event shape
{
"object": "credit_usage_event",
"id": "cue_2c5tQ...",
"amount": -25,
"type": "simulation_debit",
"unit_type": "monthly",
"resource": {"object": "simulation", "id": "sim_2c5tQ..."},
"balance_after": 1209,
"created_at": "2026-04-25T15:42:11.123Z"
}
| Field | Notes |
|---|---|
amount | Negative for debits; positive for grants and refunds. Whole units. |
type | One of simulation_debit, sweep_debit, monthly_grant, signup_grant, bounty_grant, refund, adjustment. |
unit_type | Which bucket was affected: free or monthly. |
resource | The linked simulation or submission, as a discriminated reference. null for grants and adjustments. |
balance_after | total immediately after this event committed. |
A run that crosses a bucket boundary writes two events — one monthly, one free — sharing the same resource.id.
Query parameters
| Parameter | Type | Description |
|---|---|---|
limit | int (1–100) | Page size. Default 25. |
cursor | string | Opaque cursor from a prior response's next_cursor. |
type | string | Filter by event type, e.g. simulation_debit. |
credit_type | string | Filter by bucket: free or monthly. |
created_at[gte] | ISO-8601 | Inclusive lower bound on created_at. |
created_at[lt] | ISO-8601 | Exclusive upper bound on created_at. |
The response wraps events in a cursor-paginated list:
{
"object": "list",
"data": [ ... ],
"has_more": true,
"next_cursor": "eyJwIjoiY3VlXzJ..."
}
Pass cursor=<next_cursor> on the next request. Cursors encode (created_at, id) and stay stable while the underlying rows exist.
Examples
Simulation debits since a date:
curl "https://thrustlab.com/v1/compute-units/transactions?type=simulation_debit&created_at[gte]=2026-04-18T00:00:00Z" \
-H "Authorization: Bearer key_..."
Free-bucket activity only:
curl "https://thrustlab.com/v1/compute-units/transactions?credit_type=free" \
-H "Authorization: Bearer key_..."
Low-balance webhook
When total crosses below low_balance_threshold, ThrustLab emits a credits.low_balance webhook event — once per crossing. A refund or grant that pushes you back above the threshold rearms the detector. Accounts with no recurring grant have a null threshold and receive no such event. See webhooks for registration and signature verification.
Insufficient balance (HTTP 402)
Starting a run without enough usable balance returns:
{
"error": {
"type": "insufficient_credits_error",
"code": "credits_insufficient",
"message": "This action requires 25 credits; available balance is 12.",
"required_amount": 25,
"available_balance": 12,
"currency": "credit"
}
}
available_balance excludes expired monthly units. Refill by waiting for the next cycle or upgrading your tier.