- authentication
- Secret API key as a bearer token
- billing
- Free.
Every credit movement on the account, newest first: lookups debited, monthly grants, purchased packs and plan deposits. Each row carries the signed delta, the balance_after it left, the reason, an optional reference (a Stripe session or invoice id for purchases), and via, the label of the key, widget, bulk run or monitor that spent it. Filter with since and until (ISO 8601 dates), reason and via; page with page and per_page (up to 200). The dashboard's Usage page offers the same rows as a CSV download.
Parameters
| name | in | type | description |
|---|---|---|---|
| since | query | string | Only rows on or after this date. |
| until | query | string | Only rows on or before this date. |
| reason | query | string | Only rows with this reason, e.g. email_lookup, ip_lookup, monthly_grant, purchase, subscription. |
| via | query | string | Only rows spent through this label, e.g. "api · Production". |
| page | query | integer | |
| per_page | query | integer | Default: 50. |
Example request
curl https://spaw.co/api/v1/account/ledger \ -H "Authorization: Bearer sk_live_…"
Responses
200One page of ledger rows.
{
"success": true,
"data": [
{
"id": 9812,
"delta": -1,
"balance_after": 8,
"reason": "ip_lookup",
"reference": null,
"via": "api · Production",
"created_at": "2026-09-04T10:12:44+00:00"
},
{
"id": 9801,
"delta": 10,
"balance_after": 10,
"reason": "monthly_grant",
"reference": "2026-09",
"via": null,
"created_at": "2026-09-01T00:00:03+00:00"
}
],
"meta": {
"page": 1,
"per_page": 50,
"total": 2,
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}401The key is missing, malformed, or revoked.
{
"success": false,
"error": {
"code": "UNAUTHENTICATED",
"message": "Provide a valid API key as a bearer token.",
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}422The request body could not be validated; `error.errors` lists the fields.
{
"success": false,
"error": {
"code": "VALIDATION_FAILED",
"message": "The email field is required.",
"errors": {
"email": [
"The email field is required."
]
},
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}429Over 5 requests per second for the key. Retry after the limit resets.
{
"success": false,
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Retry after the limit resets.",
"request_id": "req_01m1kgdm4xngzmbmff68g94w0c"
}
}Error codes
Failures answer { success: false, error: { code, message, request_id } }. Each code has its own page.