# Billing

> Buy credit packs through Lemon Squeezy checkout, read the credit ledger, understand plan changes, and how refunds are applied.

Source: https://akaphone-docs.pages.dev/guides/billing/

AkaPhone sells prepaid credit packs. One credit is one device-minute. See [Credits and plans](https://akaphone-docs.pages.dev/concepts/credits-and-plans/) for what each plan includes.

## Packs

| Pack id | Price | Credits | Also |
|---|---|---|---|
| `250` | $10 | 250 | Moves Free accounts to Dev |
| `1375` | $50 | 1,375 | Moves Free accounts to Dev |
| `6000` | $200 | 6,000 | Moves Free accounts to Dev |
| `team` | $199 | 6,000 | Team plan for 30 days |

Prices are in US dollars. Sales tax or VAT is added at checkout where it applies.

## Buying credits

### In the dashboard

Open **Billing**, choose a pack and click **Buy**. You are taken to a Lemon Squeezy checkout page. After paying you return to `https://akaphone.abhgnx-417.workers.dev/billing?checkout=success`, and the credits appear as soon as Lemon Squeezy confirms the order, normally within a few seconds.

### Over the API

`POST /v1/billing/checkout` returns a checkout URL for the pack. Open it in a browser to pay:

```bash title="curl"
curl -X POST https://akaphone.abhgnx-417.workers.dev/v1/billing/checkout \
  -H "Authorization: Bearer $AKAPHONE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"pack": "1375"}'
```
```typescript title="TypeScript"
const { url } = await fetch("https://akaphone.abhgnx-417.workers.dev/v1/billing/checkout", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.AKAPHONE_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ pack: "1375" }),
}).then((r) => r.json());
```
```python title="Python"
import os, requests

url = requests.post(
    "https://akaphone.abhgnx-417.workers.dev/v1/billing/checkout",
    headers={"Authorization": f"Bearer {os.environ['AKAPHONE_API_KEY']}"},
    json={"pack": "1375"},
).json()["url"]
```

```json
{ "url": "https://akaphone.lemonsqueezy.com/checkout/custom/4f1c0e7a-…" }
```

The checkout is tied to your account, so the credits go to the account that requested it, whoever pays.

## Receipts and invoices

Lemon Squeezy is the merchant of record. It emails the receipt to the address used at checkout and handles tax. For an invoice with your company details, use the link in that receipt email.

## The ledger

Every change to your balance is a row in the credit ledger: **Billing › Credit ledger** in the dashboard, or `GET /v1/billing/ledger`.

| `kind` | `delta` | `ref` | When |
|---|---|---|---|
| `grant` | +60 | `signup:usr_…` | Your first sign-in. |
| `purchase` | + pack credits | Lemon Squeezy order id | A paid order. |
| `usage` | − minutes | `dev_…:w<n>` | Device minutes, one row per device per 10-minute window. |
| `usage` | − minutes | `usr_…:YYYY-MM` | After 90 days, usage rows are combined into one row per month. |
| `refund` | − credits | `<order id>:r<amount>` | A refund (see below). |
| `adjust` | ± | varies | A manual correction by support. |

```json
{
  "entries": [
    { "id": "led_01m5vqsywgmvjvevzqnbkz", "delta": -10, "kind": "usage", "ref": "dev_s6zr7mr4f2f1:w1", "created_at": "2026-10-26T09:24:09.000Z" },
    { "id": "led_01m5vqsywgmzjsatq42611", "delta": 1375, "kind": "purchase", "ref": "4821733", "created_at": "2026-10-26T09:02:51.000Z" },
    { "id": "led_01m5vqsywgadfgngs4y1q2", "delta": 60, "kind": "grant", "ref": "signup:usr_01m5vqsywg3mxj7dyxv9q9", "created_at": "2026-10-20T15:40:12.000Z" }
  ]
}
```

Your balance is the sum of the ledger minus minutes charged in the current, not yet written, 10-minute windows. `GET /v1/me` always returns the exact current balance.

## Refunds

Refunds are issued through Lemon Squeezy. Email [hello@akaphone.com](mailto:hello@akaphone.com) with the order number from your receipt. When a refund is processed:

- **Credits are taken back in proportion** to the amount refunded: refunding half of a 1,375-credit pack removes 688 credits (rounded). Further partial refunds of the same order take back only the difference.
- **Your balance can go negative** if you already used those credits. While it is negative (strictly, below 1) you cannot create devices, and running devices stop at their next minute.
- **Refunding a Team pack**, fully or partly, ends the Team plan immediately; you return to Dev.

## Running out

- Creating a device needs a balance of at least 1 credit, otherwise `402 insufficient_credits`.
- While a device runs, the dashboard and stream viewers get a `credits.low` warning when the balance is 5 or less.
- When a minute is due and the balance is below 1, the device stops with reason `credits`. Your data on that device is gone, as with any stop, so snapshot anything you want to keep while you still have credits.
