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

# vetta plan & vetta credits

> The monthly plan, the prepaid balance, top-ups, and the usage ledger.

Two different things, and the order matters. The **plan** is the right to use the organization at all — without an active one every command outside billing is refused. **Credits** are the prepaid USD balance those commands then spend: every session debits the ledger as it runs, and a top-up credits it.

> [!NOTE]
>
> Organizations, members, API keys, and the audit trail moved to their own pages: [`vetta org`](https://vetta.sh/docs/cli/org), [`vetta keys`](https://vetta.sh/docs/cli/keys), and [`vetta audit`](https://vetta.sh/docs/cli/audit). There is **no `vetta billing` group** — the plan is `vetta plan`, the balance is `vetta credits`, and the card, the invoices and cancellation all live behind `vetta plan portal`.

## Commands

| Command | Description |
| - | - |
| `vetta plan show` | Show the plan: status, tier, period end, trial end, pending change or cancellation. |
| `vetta plan subscribe` | Get the hosted checkout link for the monthly plan (`--plan standard\|pro`). |
| `vetta plan change` | Upgrade to Pro now, or move to Standard at the end of the period (`--plan pro\|standard`). |
| `vetta plan portal` | Get the link to the hosted account page: card, invoices, cancellation. |
| `vetta credits show` | Show the balance. |
| `vetta credits topup` | Get a hosted checkout link. |
| `vetta credits ledger` | List grants and charges. |
| `vetta credits spend` | Total what was spent, over the whole range. |

## The plan

An organization starts with no plan, and a plan is what makes it usable: `GET /v1/agents`, `POST /v1/sessions` and everything else outside billing answer `402 subscription_required` until one is active. Creating an organization does not start one, and neither does a credit balance — a full balance with no plan is still refused.

There are two plans. **Standard** is **$20 per month**, and each paid period also grants 20 USD of credit; it is the only plan with a **7-day free trial**. **Pro** is **$200 per month**, and each paid period grants 200 USD of credit. So the plan buys the right to run; the credit it grants is what the running costs. Included credit rolls over — it stays in the prepaid balance and never expires.

### plan show

```bash theme={"system"}
vetta plan show
```

```json theme={"system"}
{
  "object": "subscription",
  "status": "active",
  "plan": "standard",
  "price_micro_usd": 20000000,
  "included_credit_micro_usd": 20000000,
  "current_period_end": "2026-09-22T17:30:00Z",
  "grace_until": null,
  "cancel_at_period_end": false,
  "trial_end": "2026-09-22T17:30:00Z",
  "pending_plan": null,
  "trial_eligible": false,
  "action_url": null
}
```

`plan` is `standard` or `pro` (`null` before the first subscription). A free trial reads `status: "active"` with `trial_end` set — there is no separate trial status — and `pending_plan` names a downgrade scheduled for `current_period_end`. `trial_eligible` says whether `plan subscribe` would start the free trial.

| `status` | Meaning |
| - | - |
| `none` | No plan has ever started. Every gated command is refused. |
| `active` | The organization can be used until `current_period_end`. |
| `past_due` | The last payment did not go through. Still usable until `grace_until`, then refused. |
| `canceled` | The plan ended. Every gated command is refused. |

`cancel_at_period_end` is `true` once a cancellation has been asked for: the organization stays usable until `current_period_end` and is refused after it. This command answers whether or not a plan exists, so it is always safe to run — it is the one thing a lapsed organization can still ask.

### plan subscribe

```bash theme={"system"}
vetta plan subscribe                 # Standard, with the 7-day free trial when eligible
vetta plan subscribe --plan pro      # Pro, billed today
```

```json theme={"system"}
{
  "object": "subscription",
  "status": "none",
  "plan": null,
  "price_micro_usd": null,
  "included_credit_micro_usd": null,
  "current_period_end": null,
  "grace_until": null,
  "cancel_at_period_end": false,
  "trial_end": null,
  "pending_plan": null,
  "trial_eligible": true,
  "action_url": "https://checkout.example/c/pay/cs_test_a1b2c3..."
}
```

| Flag | Description |
| - | - |
| `--plan` | `standard` (default) or `pro`. |

**The free trial.** On Standard, when `trial_eligible` is `true`, the checkout starts a 7-day free trial: a card is required, $10 of credit is granted when it starts (on an eligible card: see [Pricing](https://vetta.sh/docs/platform/pricing.md)), and it converts to $20 per month with the full \$20 of credit unless you cancel first (`vetta plan portal`). One trial per organization and one per person; otherwise the same checkout bills on the day.

`action_url` is a hosted checkout page. **Open it in a browser and pay it there** — a card cannot be typed into a terminal, so this is the one step the CLI hands back to you. Copy the URL whole; it is printed on one line and unwrapped for exactly that reason.

```bash theme={"system"}
vetta plan subscribe | jq -r .action_url     # just the URL, for `open`/`xdg-open`
```

> [!WARNING]
>
> `subscribe` opens a checkout and changes **nothing** by itself. The plan becomes `active` only when the payment provider's signed callback lands — normally a second or two after you finish the page. The command does not wait for that: it cannot see whether you opened the URL, and blocking on a payment it does not control would be a lie about what it is doing. Run `vetta plan show` when you have paid.

Running `subscribe` while a plan is already active is refused with `state_conflict` — a second checkout would be a second plan billed; use `vetta plan change` to switch tiers. To cancel, use `vetta plan portal` below — `vetta plan` has no `cancel` command, and a cancellation takes effect at the end of the period already paid for either way.

### plan change

```bash theme={"system"}
vetta plan change --plan pro         # immediate: charged now, ends a running trial
vetta plan change --plan standard    # at the end of the period already paid for
```

```json theme={"system"}
{
  "object": "subscription",
  "status": "active",
  "plan": "pro",
  "price_micro_usd": 200000000,
  "included_credit_micro_usd": 200000000,
  "current_period_end": "2026-09-22T17:30:00Z",
  "grace_until": null,
  "cancel_at_period_end": false,
  "trial_end": null,
  "pending_plan": "standard",
  "trial_eligible": false,
  "action_url": null
}
```

| Flag | Description |
| - | - |
| `--plan` | `pro` or `standard` (required). |

Upgrading to Pro takes effect at once on the card already on file: the difference for the rest of the month is charged now and the billing date stays the same. Upgrading during the free trial ends the trial and charges \$200 now. Moving back to Standard takes effect at `current_period_end` — nothing is refunded, the Pro credit already granted is kept, and until then `plan show` reads `plan: "pro"` with `pending_plan: "standard"`. Running `--plan pro` again before then takes the downgrade back. An organization with no active plan is refused with `state_conflict`; start one with `plan subscribe`. So is a plan already set to cancel at the end of its period.

### plan portal

```bash theme={"system"}
vetta plan portal
```

```json theme={"system"}
{
  "object": "billing_portal_session",
  "action_url": "https://billing.example/session/live_YWNjdF8..."
}
```

The one place the card on file, the past invoices and cancellation all live. Like `subscribe`, it hands back a URL for a browser: none of those three is a thing a terminal can do.

```bash theme={"system"}
vetta plan portal | jq -r .action_url        # just the URL, for `open`/`xdg-open`
```

The link is single-use and expires — run the command again rather than keeping one around. And like `subscribe` it changes nothing by itself: whatever you do on that page arrives back as a confirmed event a moment later, so run `vetta plan show` to see the result.

An organization that has never held a plan has no account to manage, and the command says so rather than opening an empty page:

```
$ vetta plan portal
error: not_found: this organization has no billing account to manage; start the plan with `POST /v1/credits/subscription` first (req_9k2m4p7q1w8x3v6z0b5n2c4t8r)
```

### When a command is refused

Any command on an organization with no plan fails like this, and names the command that fixes it:

```
$ vetta agent list
error: subscription_required: this organization has no active plan. Start or renew it with `POST /v1/credits/subscription` and follow `action_url`; the organization can be used again as soon as the payment is confirmed. (req_9k2m4p7q1w8x3v6z0b5n2c4t8r)
fix it with: vetta plan subscribe
```

The first line is unchanged and still leads with the `code`, so `case` statements that branch on it keep working; the remedy is a second line on stderr. Exit code is `1` — see [exit codes](https://vetta.sh/docs/cli/sessions.md#run-exit-codes).

## The balance

What the plan does *not* cover: every token an agent spends is debited from the prepaid balance below. `insufficient_credits` (402) means top up; `subscription_required` (402) means the plan above.

### show

```bash theme={"system"}
vetta credits show
```

```json theme={"system"}
{
  "object": "credit_balance",
  "balance_micro_usd": 79416537,
  "mode": "test"
}
```

`mode` is `test` for an `sk_test_…` credential and `live` for `sk_live_…`. A test-mode balance is not real money.

### topup

```bash theme={"system"}
vetta credits topup --usd 50
```

| Flag | Description |
| - | - |
| `--usd` | Amount as a decimal-dollar string (required). |

> [!WARNING]
>
> `topup` opens a hosted checkout and credits **nothing** by itself. Only the verified payment callback moves money, so the balance does not change the moment this command returns. Poll `vetta credits show` if you need to wait for it to land.

### ledger

```bash theme={"system"}
vetta credits ledger --limit 2
```

```json theme={"system"}
{
  "data": [
    {
      "id": "led_35cwx4557pj3sr9wrsgbfnx7f3",
      "type": "debit",
      "amount_micro_usd": -124,
      "balance_after_micro_usd": 79416537,
      "actor": { "type": "key", "id": "key_5d50bxwbje7b5n4a8gpkpfak38" },
      "session_id": "ses_xq5542edbac2dssv3gm6atdcr8",
      "agent_id": "agt_kt88353jaw132sjakt4sytz4a6",
      "deployment_id": null,
      "line_items": [
        { "tier": "input", "amount_micro_usd": -114 },
        { "tier": "cache_write", "amount_micro_usd": 0 },
        { "tier": "cache_read", "amount_micro_usd": 0 }
      ]
    }
  ],
  "has_more": true,
  "next_cursor": "led_..."
}
```

| Flag | Description |
| - | - |
| `--type` | `debit` \| `credit`. |
| `--session` | Attribute to one session. |
| `--agent` | Attribute to one agent. |
| `--deployment` | Attribute to one deployment. |
| `--from` / `--to` | ISO-8601 date bounds. |
| `--limit` / `--after` | Pagination. |

Each entry carries full attribution and a `line_items` breakdown by pricing tier, so a charge can always be traced to the run that caused it.

```bash theme={"system"}
vetta credits ledger --agent agt_kt88353jaw132sjakt4sytz4a6 --from 2026-08-01 --human
```

### spend

```bash theme={"system"}
vetta credits spend --from 2026-08-01
```

```json theme={"system"}
{
  "spent_micro_usd": 41873200,
  "by_tier": { "input": 30112000, "output": 9861200, "computer": 1900000 },
  "by_agent": [{ "agent_id": "agt_kt88353jaw132sjakt4sytz4a6", "spent_micro_usd": 41873200 }],
  "by_session": [{ "session_id": "ses_xq5542edbac2dssv3gm6atdcr8", "spent_micro_usd": 12004100 }]
}
```

What every matching charge spent, summed by the server: the total, by tier, and the 50 dearest agents and sessions. It takes the ledger's `--session`, `--agent`, `--deployment`, `--from` and `--to`. `--days 14` (alone) adds the company's spend per day, on `--timezone` or the company's clock. Use it for a total: adding up a page of `ledger` misses every charge past that page.

> [!NOTE]
>
> **Money is exact.** `--usd` takes a decimal-dollar string and is converted client-side to integer micro-USD. JSON output amounts are integer `*_micro_usd` (`1 USD = 1_000_000` micro-USD) so a script's arithmetic never rounds; `--human` renders dollars for reading.

> [!WARNING]
>
> A misspelled filter cannot silently widen a money query. `vetta credits ledger --sesion ses_…` exits `2` and lists the flags the command does take, rather than answering with the whole org's ledger.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.