Skip to content
Hardcount
Run it locally
Pre-1.0 · one maintainer · Stripe and cards only · no SDKs (client libraries) yet · no production users yet. Docs describe v0.9.1 (29 Oct 2026) · What’s new →

Per-grant burndown + kind subtotals

GET
/v1/credits/grants/{customer_id}
curl --request GET \
--url http://localhost:8080/v1/credits/grants/example \
--header 'Authorization: Bearer <token>'

The customer’s credit blocks with drawdown state — granted / drawn / remaining per grant, expiry, and remaining per currency split by cost-basis class (commit = money-backed, promotional = free, other = legacy/adjustments). include_exhausted=true adds fully-drawn blocks for history. Each grant’s consumed_cents also counts credit no invoice used: expired_cents, the part that expired unused; retired_cents, commit credit taken back when the invoice that funded it was voided or refunded by a credit note; and deducted_cents, the part an operator deduction (a negative adjustment) drew from this grant. The credit invoices actually used is consumed_cents - expired_cents - retired_cents - deducted_cents.

customer_id
required
string
include_exhausted
boolean

Grants with remaining + kind subtotals

Media typeapplication/json

A customer’s credit blocks, newest first, with the remaining credit added up by currency and kind.

object
grants
required
Array<object>

One block of credit on a customer’s balance (a grant or a positive adjustment) and how much of it is left.

object
id
required

The ledger entry that added the credit.

string
entry_type
required

grant or adjustment.

string
currency
required

The block’s currency, uppercase.

string
grant_kind

Absent for unclassified credit.

string
Allowed values: commit promotional
description
required
string
amount_cents
required

The credit the block started with.

integer format: int64
consumed_cents
required

Everything drawn from the block: used by invoices, expired, retired and deducted.

integer format: int64
remaining_cents
required
integer format: int64
expired_cents
required

The part that expired unused.

integer format: int64
retired_cents
required

Commit credit taken back when the invoice that paid for it was voided, or refunded by a credit note.

integer format: int64
deducted_cents
required

The part an operator removed with a negative adjustment.

integer format: int64
expires_at

The credit can be drawn up to and including this instant; a period invoice draws it when its period ends at or before it. The dashboard sends the local midnight after the picked day.

string format: date-time
source_invoice_id

For a commit block, the invoice that paid for it.

string
created_at
required
string format: date-time
remaining_by_currency
required

One entry per currency with credit left, ordered by currency.

Array<object>
object
currency
required
string
commit_remaining_cents
required

Remaining credit the customer paid for (commit).

integer format: int64
promotional_remaining_cents
required

Remaining free credit (promotional).

integer format: int64
other_remaining_cents
required

Remaining credit with no kind, such as adjustments and credit-note credit.

integer format: int64

Example

{
"grants": [
{
"grant_kind": "commit"
}
]
}

No customer with this ID in this tenant and mode.

Media typeapplication/json
object
error
object
type

One of invalid_request_error, authentication_error, rate_limit_error or api_error. Every error the API answers has this shape, including an unknown path (404, code route_not_found) and a method the path does not take (405, code method_not_allowed, with an Allow header). The few exceptions are listed in docs/api-surface.md.

string
code
string
message
string
request_id
string
param

The request field the error is about. Sent only when the error names one. A request body may hold only the fields its operation lists, spelled and cased as listed: any other field, or one the server sets (such as id), is refused with 422 and param naming it. An operation with no request body lists no fields: send no body, {} or null. The Stripe and Postmark webhooks and the LiteLLM callback take their sender’s body as it comes.

string

Example

{
"error": {
"type": "invalid_request_error"
}
}