Concepts
This page lists what Spend Gateway enforces today. Where something is missing or partial, it says “Not yet”.
Grants
A spend grant lets one app spend on its owner’s behalf. It records:
| Field | Meaning |
|---|---|
owner_uid | The owner: the subject of the token that created the grant. |
app_id | The app the grant is for. Any string you choose, 1 to 128 bytes. |
limit_units | The most the grant can settle, per period or in total; see Periods. |
per_call_cap | The most one reservation may hold. |
period | day, month or never, if set; see Periods. |
settlement | Prepaid or Byok; see Settlement. |
revoked | Whether the owner has revoked it. |
available | What the grant can still draw now; see Balances. |
- Owner only. Only the owner can read, change or revoke a grant. Anyone
else gets
404, the same as for a grant that doesn’t exist. - One active grant per app. An owner has at most one unrevoked grant for
each
app_id. Creating a second is409; revoke the first, then create the new one. - Revoking is final. A revoked grant can’t be drawn on again, changed
(
409) or restored. It stays in the owner’s list with"revoked": trueandavailable0. Once nothing is held against it, its balance is final, and itsdebitedcounts every unit ever settled under it. - At most 100 grants per owner that are live or still hold a reservation.
Creating another is
409; revoke one first. Revoked grants with nothing held don’t count.
How a draw works
Spend Gateway does not do the work or price it. A Stackwell service that does metered work for an app (Compute Gateway, for example) draws on the owner’s grant for that app in two steps:
- Reserve before the work starts. Spend Gateway holds up to the units the service asks for, less if a cap leaves less room. If it can hold nothing, it refuses the reservation.
- Settle when the work ends, with the units actually used, which can’t be more than were held. The rest of the hold is released. Settling the same reservation twice never charges twice.
While a reservation is open, its units count as reserved in the grant’s
balance.
Periods
Until its limit is changed, a grant can settle at most limit_units in one
period, counting what is reserved. A grant created without a period is a
never grant: limit_units is its total.
period | The count resets |
|---|---|
day | 24 hours after the period started |
month | 30 days after the period started |
never | Never |
The first period starts when the grant is created. When a period has run out, the next draw starts a new one.
Settlement
settlement says what else limits a draw. It is set when the grant is created
and can’t be changed. Note the capitals.
settlement | Wallet | Notes |
|---|---|---|
Prepaid (default) | Each draw also needs balance in the owner’s wallet, and settling takes units from it. | |
Byok | Not checked, never drawn. | Needs a period. Meant for spend paid for outside Stackwell, such as a model provider billing a key the person supplied. |
"Free" is refused with 400.
Wallets
Each owner has one wallet, shared by all of their Prepaid grants. A
Prepaid grant can never draw more than the wallet holds.
- A new wallet is empty, and creating or changing a grant adds nothing to it.
- Spend Gateway takes no payments and never holds anyone’s money. Wallet units are credits Stackwell issues, with no cash value. A person or developer has no way to add balance; only Stackwell can.
So a Prepaid grant on an empty wallet can’t draw anything: available is
0, and a service that tries to reserve against it is refused.
Balances
GET /v1/spend/grants/{id}/balance returns:
| Field | Prepaid | Byok |
|---|---|---|
limit_units | The grant’s limit_units | The period’s limit |
debited | Units settled under this grant, ever | Units settled in the current period |
reserved | Units held by this grant’s open reservations | The same |
available | The wallet’s balance less every hold on it, or what the period’s limit leaves less this grant’s holds, whichever is less | The period’s limit less debited and reserved |
For a Prepaid grant, available is the most a reservation against it could
hold right now. All the owner’s grants share one wallet, so a hold made under
any of them lowers available on every other grant too.
Changing a limit
PATCH /v1/spend/grants/{id} sets a new limit_units, raising or lowering
it. The new limit is what the grant may draw from then on: per period for a
grant with a period, and in total otherwise. It can’t go below what the
grant has used plus what it holds in reserve (409): for a grant with a
period, what it has used in the current period only, so a day grant that
spent heavily yesterday can still be lowered today.
PATCH changes only limit_units. A Prepaid grant keeps its
per_call_cap; a Byok grant’s per_call_cap rises to the new limit when
the limit is raised above it.
Usage
Each settlement adds a usage record, even one that used nothing: the
reservation, the grant, the units, and when. GET /v1/spend/usage returns
all of the owner’s records in one response; the list is not paged.