> ## Documentation Index
> Fetch the complete documentation index at: https://docs.truscan.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Credits and usage

> Your balance, the monthly free grant, topping up, and the audit trail.

Truscan runs on prepaid credits. Each request debits your balance; when the
balance cannot cover a request, the request is refused rather than silently
queued.

## The free grant

Every account receives **\$10.00 in credits each month**, applied automatically
on your first request in a new billing period. Unused grant credits do not roll
over.

At `instant` rates, \$10.00 covers roughly 1,400 searches before extraction costs.

## Checking your balance

```bash theme={null}
curl https://api.truscan.co/api/billing/account \
  -H "Authorization: Bearer $TRUSCAN_API_KEY"
```

```json theme={null}
{
  "success": true,
  "result": {
    "user_id": "usr_...",
    "balance_micros": 9970000,
    "balance_display": "$9.97",
    "lifetime_spent_micros": 30000,
    "free_grant_micros": 10000000,
    "granted_period": "2026-09"
  }
}
```

## Topping up

`POST /api/billing/checkout` returns a hosted payment page. Send the amount in
**cents**, minimum $5.00, maximum $5,000.00:

```bash theme={null}
curl -X POST https://api.truscan.co/api/billing/checkout \
  -H "Authorization: Bearer $TRUSCAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount_cents": 2000}'
```

```json theme={null}
{
  "success": true,
  "result": {
    "payment_id": "pay_...",
    "checkout_url": "https://checkout.example.com/...",
    "amount_cents": 2000,
    "credits_micros": 20000000,
    "credits_display": "$20.00"
  }
}
```

Send the user to `checkout_url`. Credits are applied when the payment provider
confirms the charge, not when the page is opened.

<Note>
  Credits are applied asynchronously. Poll `GET /api/billing/account` or
  `GET /api/billing/payments` to confirm a top-up landed.
</Note>

## Usage

`GET /api/billing/usage` breaks spending down by operation:

<ParamField query="days" type="integer" default="30">
  Look-back window. Maximum 365.
</ParamField>

<ParamField query="limit" type="integer" default="100">
  Individual entries to return. Maximum 500.
</ParamField>

```json theme={null}
{
  "result": {
    "since": "2026-08-20T00:00:00Z",
    "total_micros": 30000,
    "total_display": "$0.03",
    "by_operation": [
      { "operation": "search", "units": 2, "cost_micros": 14000 },
      { "operation": "content", "units": 16, "cost_micros": 16000 }
    ],
    "entries": []
  }
}
```

## The ledger

`GET /api/billing/ledger` is the audit trail, every movement of credit, newest
first, each with the balance it produced:

```json theme={null}
{
  "result": [
    {
      "id": "led_...",
      "delta_micros": -15000,
      "balance_after_micros": 9970000,
      "kind": "usage",
      "reason": "search:instant",
      "created_at": "2026-09-19T10:31:00Z"
    }
  ]
}
```

`kind` is one of `grant` (the monthly free credits), `topup` (a payment), or
`usage` (a charge).

## Running out

When the balance cannot cover a request, the API returns `402`:

```json theme={null}
{
  "success": false,
  "message": "You do not have enough credits for this request.",
  "result": { "code": "insufficient_credits" }
}
```

Top up, or wait for the next monthly grant.
