putty
API ReferenceLedger

List the credit packs on sale

The credit packs a caller can buy, cheapest first, with the credits each buys when paid in a stablecoin and the (larger) number it buys when paid in $PUTTY. The `tokens` array is what `POST /billing/orders` accepts. Prices live here and in the dashboard, never on the marketing homepage.

GET
/billing/packs

The credit packs a caller can buy, cheapest first, with the credits each buys when paid in a stablecoin and the (larger) number it buys when paid in $PUTTY. The tokens array is what POST /billing/orders accepts.

Prices live here and in the dashboard, never on the marketing homepage.

Response Body

application/json

application/json

application/json

curl -X GET "https://example.com/billing/packs"
{  "packs": [    {      "id": "string",      "name": "string",      "usd": "string",      "credits": 1,      "tokenCredits": 1,      "usdPerCredit": "string"    }  ],  "tokens": [    "string"  ]}

Page the caller's credit movements GET

The append-only ledger of every credit movement on the caller's account, newest first: grants, purchases, and spends. A balance is always the sum of these rows, so this page can explain any balance without trusting a stored counter. A `delta` of 0 is a real row and means a free action — a security review sub-run, a price or chain read — that was still worth recording, so the history shows what the user did rather than only what they paid for.

Quote a credit pack at the server's token price POST

Quotes a credit pack in a token and returns the amount to send, priced from a **Chainlink Data Feed on Robinhood Chain read at request time** — the price is never taken from the request and never assumed. `usdg` is priced through the `USDG / USD` feed and `eth` through `ETH / USD`. The response carries `priceSource`: the aggregator proxy, the exact round id, and when that round was published, so a client can call `latestRoundData()` on the same address and confirm the rate it was given. `roundId` is a string because it is an 80-bit counter that does not fit a JSON number. A round older than **twice the feed's own heartbeat** is refused rather than quoted. Every feed on this chain reports once a day, which is correct for a stablecoin whose price does not move intraday, so a shorter bound would refuse a healthy feed. Two heartbeats tolerates one missed update and no more. **`tokenPriceUsd` in the request is ignored.** The rate is the server's; a caller that names one does not get it. The field is still accepted so an older client is not broken by the change. This is the pricing half of the order. Creating the payment order and the unsigned transaction to sign needs a deployed payment receiver contract, and there is not one yet — so the response is a quote, and the 201 order response is not yet returned by this route. Card checkout through the Business Kit is a separate flow and is unaffected.