references/examples/usage-metrics.md
# Usage metrics examples
## Get overall usage for a time range
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31
```
Response:
```json
{
"metrics": [
{
"date": "2026-07-25T00:00:00.000Z",
"items": [
{ "slug": "integration.peopleDataLabs.action.queryPeople", "count": 174, "groupBy": null },
{ "slug": "native.modelAsk", "count": 0.5, "groupBy": null },
{ "slug": "success", "count": 1043, "groupBy": null },
{ "slug": "error", "count": 32, "groupBy": null },
{ "slug": "insert", "count": 24, "groupBy": null }
]
}
]
}
```
Each item has a `slug` (usage type) and `count`. When `--group-by` is used, `groupBy` contains the resource UUID/slug.
**`count` is not always credits.** Unqualified, the array interleaves all three usage units: `integration.*` / `native.*` slugs are credits, `success` / `error` are **node executions** (credits = count / 100), `insert` is records written. Isolate one with `--unit billing.credits`, `--unit orchestration.executions`, or `--unit storage.records` — the only three accepted values.
## Isolate the execution charge
Every node execution bills 0.01 credits, and it is attributed to no node — this is the only place it surfaces.
```bash
cargo-ai billing usage get-metrics \
--from 2026-07-25 --to 2026-07-25 --unit orchestration.executions
# → [{"slug":"error","count":32},{"slug":"success","count":1043}]
# → 1,075 executions = 10.75 credits
```
Same day, provider spend for comparison:
```bash
cargo-ai billing usage get-metrics \
--from 2026-07-25 --to 2026-07-25 --unit billing.credits
# → sum of items[].count = ~276 credits
```
Here orchestration is ~4% because the day was action-heavy. On an action-light sweep the ratio inverts and executions become the largest line item. See [`../../SKILL.md`](../../SKILL.md) → "The execution charge".
## Group by workflow
See which workflows consume the most credits.
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--group-by workflow_uuid
# → Each item has groupBy = workflow UUID
# → Cross-reference with: cargo-ai orchestration workflow list
```
## Group by connector
See which connectors (e.g. Salesforce, HubSpot) are used most.
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--group-by connector_uuid
# → Cross-reference with: cargo-ai connection connector list
```
## Group by integration
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--group-by integration_slug
```
## Group by model
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--group-by model_uuid
# → Cross-reference with: cargo-ai storage model list
```
## Group by agent
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--group-by agent_uuid
# → Cross-reference with: cargo-ai ai agent list
```
## Filter usage to a specific workflow
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--workflow-uuid <uuid>
```
## Filter usage to a specific agent
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--agent-uuid <uuid>
```
## Filter usage to a specific connector
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--connector-uuid <uuid>
```
## Filter usage to a specific integration
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--integration-slug <slug>
```
## Specify unit (credits)
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--unit credits
```
## Combine group-by with filter
Usage for a specific workflow, grouped by connector.
```bash
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--workflow-uuid <uuid> \
--group-by connector_uuid
```
## Check subscription and remaining credits
```bash
cargo-ai billing subscription get
```
Response:
```json
{
"subscription": {
"plan": "self-serve",
"subscriptionStatus": "active",
"subscriptionAvailableCreditsCount": 10000,
"subscriptionCreditsUsedCount": 3200,
"startAt": "2025-01-01T00:00:00Z",
"resetAt": "2025-02-01T00:00:00Z"
}
}
```
Remaining credits = `subscriptionAvailableCreditsCount - subscriptionCreditsUsedCount`.
```bash
# Invoice history (amounts in cents — divide by 100 for dollars)
cargo-ai billing subscription get-invoices
# Card on file
cargo-ai billing subscription get-credit-card
# Open Stripe portal for self-service billing
cargo-ai billing subscription create-portal-session
```
## Compare usage across two periods
```bash
# This month
cargo-ai billing usage get-metrics \
--from 2025-02-01 --to 2025-02-28
# Last month
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31
# → Compare metrics[].items[].count values to spot trends
```
## Monthly usage report (full flow)
```bash
# 1. Overall usage
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31
# 2. Break down by workflow
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--group-by workflow_uuid
# 3. Break down by connector
cargo-ai billing usage get-metrics \
--from 2025-01-01 --to 2025-01-31 \
--group-by connector_uuid
# 4. Check remaining credits
cargo-ai billing subscription get
```
references/response-shapes.md
# Response shapes
JSON response structures returned by Cargo CLI commands used in the `cargo-billing` skill.
## cargo-ai billing usage get-metrics
```json
{
"metrics": [
{
"date": "2026-07-25T00:00:00.000Z",
"items": [
{ "slug": "integration.peopleDataLabs.action.queryPeople", "count": 174, "groupBy": null },
{ "slug": "integration.serper.action.search", "count": 27.35, "groupBy": null },
{ "slug": "native.modelAsk", "count": 0.5, "groupBy": null },
{ "slug": "success", "count": 1043, "groupBy": null },
{ "slug": "error", "count": 32, "groupBy": null },
{ "slug": "insert", "count": 24, "groupBy": null }
]
}
]
}
```
**With no `--unit`, three different quantities share one `items[]` array.** In the response above, `174` is credits, `1043` is *node executions*, and `24` is records written. Identify the unit from the slug:
| Slug shape | Unit | `count` is |
|---|---|---|
| `integration.<slug>.action.<action>`, `integration.<slug>.chat`, `integration.<slug>.extractor.<name>`, `native.<action>` | `billing.credits` | Credits (fractional) |
| `success`, `error` | `orchestration.executions` | Node executions — **credits = count / 100** |
| `insert` | `storage.records` | Records written |
`--unit` takes exactly `billing.credits`, `orchestration.executions`, or `storage.records`; any other value returns `400` listing those three. Pass it whenever the number feeds an estimate. The execution rows reconcile one-for-one with `SELECT execution_status, count() FROM spans` in `orchestration query execute`.
When `--group-by` is specified, `groupBy` contains the resource identifier:
```json
{
"metrics": [
{
"date": "2025-01-15T00:00:00Z",
"items": [
{ "slug": "enrichment", "count": 100, "groupBy": "workflow-uuid-1" },
{ "slug": "enrichment", "count": 50, "groupBy": "workflow-uuid-2" }
]
}
]
}
```
**Key fields:** `metrics[].date`, `metrics[].items[].slug` (usage type), `metrics[].items[].count` (units depend on the slug — see above), `metrics[].items[].groupBy`.
The response has exactly one top-level key, `metrics`. There is no `totalUsage` — sum `items[].count` yourself, within one unit.
## cargo-ai billing subscription get
```json
{
"subscription": {
"uuid": "...",
"workspaceUuid": "...",
"plan": "self-serve",
"cadence": "monthly",
"subscriptionStatus": "active",
"subscriptionAvailableCreditsCount": 10000,
"subscriptionCreditsUsedCount": 3200,
"additionalAvailableCreditsCount": 0,
"fixedPrice": 9900,
"conversionRate": 1,
"hasCredits": true,
"startAt": "2025-01-01T00:00:00Z",
"resetAt": "2025-02-01T00:00:00Z",
"endAt": null,
"topup": null,
"createdAt": "2025-01-01T00:00:00Z",
"updatedAt": "2025-01-15T00:00:00Z"
}
}
```
**Key fields:** `plan` (`self-serve` or `enterprise`), `subscriptionStatus`, `subscriptionAvailableCreditsCount`, `subscriptionCreditsUsedCount`, `startAt`, `resetAt`.
Remaining credits = `subscriptionAvailableCreditsCount - subscriptionCreditsUsedCount`.
## cargo-ai billing subscription get-invoices
```json
{
"invoices": [
{
"id": "inv_...",
"isPaid": true,
"amount": 9900,
"currency": "usd",
"dueDate": "2025-02-01T00:00:00Z",
"url": "https://..."
}
]
}
```
**Key fields:** `id`, `isPaid` (boolean), `amount` (in cents — divide by 100 for dollars, e.g. `9900` = $99.00), `url` (link to the invoice).
## cargo-ai billing subscription create-portal-session
```json
{
"portalSession": {
"url": "https://billing.stripe.com/session/..."
}
}
```
Open `portalSession.url` in a browser to access the Stripe self-service billing portal.
## cargo-ai billing subscription update-payment-method
```json
{
"ok": true,
"status": "updated",
"creditCard": {
"brand": "visa",
"last4": "4242",
"expMonth": 12,
"expYear": 2030
}
}
```
**Key fields:** `creditCard` describes the card now on file — the only card data ever returned. `creditCard` is absent if the card could not be read back straight after the update; the update still succeeded.
On failure the command exits non-zero with `{"errorMessage": "..."}` plus a `reason` of `cardDeclined`, `authenticationRequired`, or `paymentMethodNotFound`. A `cardDeclined` carries the issuer's `declineCode` — see [`troubleshooting.md`](troubleshooting.md).
## cargo-ai billing subscription get-credit-card
```json
{
"creditCard": {
"brand": "visa",
"last4": "4242",
"expMonth": 12,
"expYear": 2030
}
}
```
`creditCard` is `undefined` when no card is on file — the normal state for a workspace still on the free tier.
references/troubleshooting.md
# Troubleshooting
Common errors and recovery steps for `cargo-billing` commands.
## General
| Symptom | Cause | Fix |
|---------|-------|-----|
| `{"errorMessage": "..."}` with non-zero exit | Any CLI error | Read the `errorMessage` — it usually says exactly what's wrong |
| `command not found: cargo-ai` | CLI not installed or not in PATH | Run `npm install -g @cargo-ai/cli` or prefix with `npx @cargo-ai/cli` |
| `Unauthorized` or `Forbidden` | Bad or expired credentials | Re-run `cargo-ai login --oauth` (browser sign-in) or `cargo-ai login --token <token>`; verify with `cargo-ai whoami` |
## Usage metrics
| Symptom | Cause | Fix |
|---------|-------|-----|
| Empty metrics (no items) | Date range has no activity, or wrong format | Verify dates are `YYYY-MM-DD`; try a wider range; confirm the workspace had activity in that period |
| `--group-by` returns items with null `groupBy` | Some usage isn't attributable to that dimension | This is expected — unattributed usage shows `groupBy: null` |
| Metrics don't match expectations | Filtering by wrong resource UUID | Re-discover UUIDs with `play list`, `tool list`, `connector list`, or `agent list` |
## Subscription and billing
| Symptom | Cause | Fix |
|---------|-------|-----|
| `subscription get` returns `Forbidden` | Token lacks billing permissions | Use a token with admin access; check workspace settings under **Settings > API** |
| Invoice amounts look wrong | Amounts are in cents, not dollars | Divide `amount` by 100 for the dollar value |
| `create-portal-session` returns an error | Subscription not active or no Stripe setup | Verify the workspace has an active paid subscription |
## Adding a card
| Symptom | Cause | Fix |
|---------|-------|-----|
| `cardDeclined` with a `declineCode` | The issuer refused the zero-amount verification | Read `declineCode`. On a spend-limited virtual card this usually means the budget or merchant restrictions exclude us — ask the cardholder to raise the limit, then retry |
| `authenticationRequired` | The card requires 3-D Secure, which cannot be completed without the cardholder | Re-run `update-payment-method` with no arguments and give the user the hosted-form URL |
| `paymentMethodNotFound` | The details did not resolve to a card we can use | Re-check the number and expiry with the user |
| `Rate limit exceeded` on `update-payment-method` | More than 10 card updates in an hour for this workspace | Wait for `retryAfter`. Repeatedly retrying a declined card is what exhausts this — fix the decline cause first |
| Stripe rejects the card before Cargo sees it (`code`, `param` in the error) | The number, expiry, or CVC is malformed | The `param` field names the bad field; correct it with the user |
| `no Stripe publishable key configured` | The Cargo environment is missing `STRIPE_PUBLIC_KEY` | Environment misconfiguration, not a user error — report it; the hosted-form flow (no arguments) still works |
| Hosted form times out | Nobody completed the form in the window | Re-run with a longer `--timeout`, or confirm with `get-credit-card` — the card may have landed after the wait ended |
skill-metadata.json
{
"$comment": "Generated by .github/scripts/skills-metadata.mjs — do not hand-edit. Regenerate with: node .github/scripts/skills-metadata.mjs --write .",
"name": "cargo-billing",
"version": "2.0.0",
"documents": [
{
"path": "SKILL.md",
"kind": "entrypoint",
"title": "Cargo CLI — Billing"
},
{
"path": "references/examples/usage-metrics.md",
"kind": "example",
"title": "Usage metrics examples"
},
{
"path": "references/response-shapes.md",
"kind": "reference",
"title": "Response shapes"
},
{
"path": "references/troubleshooting.md",
"kind": "reference",
"title": "Troubleshooting"
}
],
"contentHash": "d5e316090aed9cd788411c1d58738f0076e1263bdfd881110fb7ad75268270d6"
}
SKILL.md
---
name: cargo-billing
description: "Understand what Cargo is costing — remaining credits, usage broken down by workflow, connector, or agent, subscription state, and invoice history. Triggers: \"how many credits do I have left\", \"what did that cost\", \"why is my bill so high\", \"am I about to run out\", \"will this fit in our budget\", \"show me my invoices\", \"how much have I spent this month\", \"what plan am I on\", \"what do I get for free\", \"how many free credits\", \"can I afford this run\", \"add a card\", \"update my payment method\", \"why was my card declined\". Needs a token with admin access. Skip when: attributing spend to specific nodes or cutting a play cost — use cargo-diagnostics."
version: "2.0.0"
compatibility: Requires @cargo-ai/cli (npm). Sign in or create an account with `cargo-ai login --email` (emailed code, no browser), `--oauth`, or an API token
homepage: https://github.com/getcargohq/cargo-skills
metadata:
author: getcargo
openclaw:
requires:
bins:
- cargo-ai
install:
- kind: node
package: "@cargo-ai/cli@latest"
bins:
- cargo-ai
homepage: https://github.com/getcargohq/cargo-skills
---
# Cargo CLI — Billing
Billing and credit management: pulling usage metrics, checking subscription status, viewing invoices, and managing credits.
> See `references/response-shapes.md` for full JSON response structures.
> See `references/troubleshooting.md` for common errors and how to fix them.
> See `references/examples/usage-metrics.md` for usage metric and subscription examples.
## Bootstrap
Already signed in (`cargo-ai whoami` returns a workspace)? Skip to the next section.
```bash
npm install -g @cargo-ai/cli # no global install? prefix every command with `npx @cargo-ai/cli`
cargo-ai login --email you@company.com # emailed code, no browser; creates the account on first use
# alternatives: --oauth (browser) · --token <api-token> (CI)
cargo-ai whoami # confirm the active workspace before any write
```
Every command prints JSON to stdout; failures exit non-zero with `{"errorMessage": "..."}`. Anything that creates a run or a batch is async — pass `--wait-until-finished` or poll the matching `get`. **Admin-only:** every command in this skill requires a token with admin access on the workspace. Non-admin tokens return `{"errorMessage":"forbidden"}`. When the full skill bundle is installed, [`../cargo/references/prerequisites.md`](../cargo/references/prerequisites.md) adds the CLI version pin, token scopes, and the admin-only surface.
## Discover resources first
Usage metrics can be filtered and grouped by resource UUID. Discover them before querying.
```bash
cargo-ai orchestration play list # all plays (name, workflowUuid)
cargo-ai orchestration tool list # all tools (name, workflowUuid)
cargo-ai ai agent list # all agents (uuid, name)
cargo-ai connection connector list # all connectors (uuid, name, integrationSlug)
cargo-ai storage model list # all models (uuid, name, slug)
```
## Quick reference
```bash
cargo-ai billing usage get-metrics --from <YYYY-MM-DD> --to <YYYY-MM-DD>
cargo-ai billing usage get-metrics --from <YYYY-MM-DD> --to <YYYY-MM-DD> --group-by workflow_uuid
cargo-ai billing subscription get
cargo-ai billing subscription get-invoices
cargo-ai billing subscription update-payment-method --card-number <number> --card-exp <MM/YYYY> --card-cvc <cvc>
cargo-ai billing subscription create-portal-session
```
## Estimating cost before running a batch
Before triggering a large batch, estimate credit consumption to avoid unexpected charges.
**Step 1 — Check current credit balance:**
```bash
cargo-ai billing subscription get
# → subscriptionAvailableCreditsCount - subscriptionCreditsUsedCount = remaining credits
```
**Step 2 — Estimate cost from a sample run:**
Run the workflow on a single record first and measure credits consumed:
```bash
# Run on one record
cargo-ai orchestration run create --workflow-uuid <uuid> --data '{...}'
# → poll to completion
# Check credits used for that run
cargo-ai billing usage get-metrics \
--from <today> --to <today> \
--workflow-uuid <uuid>
# → metrics[].items[] for that workflow (the response has one key, `metrics` — there is no `totalUsage`)
```
**Step 3 — Project batch cost:**
```
estimated_cost = (credits_per_record × number_of_records) # provider actions
+ (nodes_per_record × number_of_records / 100) # execution charge
```
The second term is the 0.01-credit-per-execution platform charge ("The execution charge" below). A sample run measures it for free — the record's execution count is `length(run.executions)`, or one row of `--unit orchestration.executions` for the sample window. Leave it out and every step-heavy graph is under-quoted.
Compare against `subscriptionAvailableCreditsCount - subscriptionCreditsUsedCount` before proceeding.
**Step 4 — Monitor during the batch:**
```bash
# Check running costs mid-batch
cargo-ai billing usage get-metrics \
--from <start-date> --to <today> \
--workflow-uuid <uuid>
```
**Cost levers:**
| Action | Effect |
|---|---|
| Use a cheaper model (e.g. `gpt-4o-mini` vs `gpt-4o`) | Significant reduction for AI nodes |
| Add `filter` nodes early in the graph | Skip ineligible records before expensive connector calls |
| Set `fallbackOnFailure: false` | Stop the run early on failures instead of continuing to downstream nodes |
| Reduce `maxSteps` on agent nodes | Limit how many tool calls an agent can make per record |
| Cut node count — collapse chained `variables`, fold branch pairs into one `switch` | 0.01/execution × records; the only lever for a graph whose spend is steps, not providers |
> To find out **which** node or provider dominates a play's spend before picking a lever, follow the attribution runbook in [`../cargo-diagnostics/references/play-optimize-credits.md`](../cargo-diagnostics/references/play-optimize-credits.md).
## Usage metrics
Pull credit and usage data for any time range, optionally filtered and grouped.
```bash
# Basic usage for a period
cargo-ai billing usage get-metrics --from <start-date> --to <end-date>
# Group by dimension
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --group-by workflow_uuid
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --group-by connector_uuid
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --group-by integration_slug
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --group-by model_uuid
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --group-by agent_uuid
# Filter by specific resource
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --workflow-uuid <uuid>
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --agent-uuid <uuid>
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --connector-uuid <uuid>
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --integration-slug <slug>
# One unit at a time — the three below are the only accepted values
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --unit billing.credits
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --unit orchestration.executions
cargo-ai billing usage get-metrics --from <start-date> --to <end-date> --unit storage.records
```
`--group-by` values: `workflow_uuid`, `connector_uuid`, `model_uuid`, `integration_slug`, `agent_uuid`.
Available filters: `--workflow-uuid`, `--model-uuid`, `--connector-uuid`, `--integration-slug`, `--slug`, `--agent-uuid`. Combine with `--group-by` and `--unit`.
### The three usage units
`--unit` takes exactly `billing.credits`, `orchestration.executions`, or `storage.records` — anything else is a `400` that lists them. **With no `--unit`, all three come back interleaved in the same `items[]` array**, and their `count` fields are not the same quantity. Read the unit off the slug:
| Unit | Slugs in `items[]` | What `count` is |
|---|---|---|
| `billing.credits` | `integration.<slug>.action.<action>`, `native.<action>`, `integration.<slug>.chat`, `integration.<slug>.extractor.<name>` | Credits (fractional) |
| `orchestration.executions` | `success`, `error` | **Node executions**, counted one-for-one — not credits |
| `storage.records` | `insert` | Records written |
An unqualified call that shows `{"slug":"success","count":1043}` next to `{"slug":"integration.peopleDataLabs.action.queryPeople","count":174}` is reporting 1,043 *executions* beside 174 *credits*. Pass `--unit` whenever the number is going into an estimate.
### The execution charge
**Every node execution bills 0.01 credits — 1 credit per 100 executions.** It applies to every node kind and every node, including the structural natives that carry no provider price: `branch`, `filter`, `switch`, `split`, `group`, `variables`, `start`, `end`. There is no free step in a workflow.
This charge is **not attributed per node**. `run get` → `executions[].creditsUsedCount` and the `spans.execution_credits_used_count` column both carry the *provider* cost alone, and read `0` on a native node that nonetheless billed. Node-by-node attribution therefore under-counts every graph, and the shortfall grows with step count, not with spend.
The only surface that shows it:
```bash
cargo-ai billing usage get-metrics --from <YYYY-MM-DD> --to <YYYY-MM-DD> --unit orchestration.executions
# → items[] = [{"slug":"success","count":<executions>}, {"slug":"error","count":<executions>}]
# credits = (success + error) / 100
```
Cross-check against the runtime tables, which agree row-for-row:
```bash
cargo-ai orchestration query execute \
"SELECT execution_status, count() AS executions, count() / 100 AS credits
FROM spans WHERE execution_started_at >= '<YYYY-MM-DD>' GROUP BY execution_status"
```
**Why it matters for estimates.** A graph's cost has two terms:
```
credits = (provider cost per record × records) + (nodes per record × records ÷ 100)
```
The second term is invisible in the credits cost table, which prices *actions*, not *steps*. It is small next to an action-heavy play (a LinkedIn enrich on every record dwarfs its 8 steps) and dominant on step-heavy, action-light ones — a 12-node routing sweep over 20,000 records is 2,400 credits with no provider call at all. Errored executions bill too, so a graph that fails late bills its whole prefix.
**Tools fan out.** A tool node is one execution *plus* every node inside the tool's own graph, each billed separately. Extracting a subgraph into a tool is a debuggability win, not a cost saving — it adds one execution per record on top of what the internals already cost. When a graph's execution count exceeds its visible node count, tool nodes are the first place to look: group by `node_slug` in `spans` to find them.
## Subscription and credits
```bash
cargo-ai billing subscription get # current plan, credits used/available, period dates
cargo-ai billing subscription get-invoices # invoice history (amounts in cents)
cargo-ai billing subscription get-credit-card # card on file
cargo-ai billing subscription update-payment-method # add or replace the card (see below)
cargo-ai billing subscription create-portal-session # Stripe portal URL for self-service billing
```
Remaining credits = `subscriptionAvailableCreditsCount - subscriptionCreditsUsedCount` from `subscription get`.
**Note:** Invoice amounts are returned in cents. Divide by 100 for the dollar value.
### The free tier
A new account starts with **100 free credits and no card on file**. When `subscription get` shows a fresh or near-fresh balance, answer cost questions against that budget rather than as an abstract number — "you've used 12 of your 100 free credits" is the useful answer to "how am I doing?", and it is also the honest one when the user is deciding whether to keep going.
What 100 credits buys, as ballpark anchors (per-action costs in [`../cargo-gtm/references/credits-cost-table.md`](../cargo-gtm/references/credits-cost-table.md)):
| Work | Cost | 100 credits ≈ |
|---|---|---|
| Source leads — `salesNavigator.searchLeads` | 0.02/record | ~5,000 leads |
| Enrich from a LinkedIn URL + verified email — `aiArk.enrichPerson` | 0.1 | ~1,000 people |
| Verify an email — `waterfall.verifyEmail` | 0.1 | ~1,000 checks |
| Full contact enrichment — `waterfall.enrichContact` | 2 | ~50 contacts |
| Find a phone — `FullEnrich.findPhone` | 6 | ~16 numbers |
The [quickstart demo](../cargo-quickstart/SKILL.md) spends about **0.5**. Phone lookups are the fastest way to burn a free tier, so phone is the **guarded lever**: the escalation tier runs 3–7 credits/record, ~10× email, and never belongs in a default chain — it enters a plan only on explicit user request, on qualified leads only. Full spend rules in [`../cargo-gtm/references/cost-discipline.md`](../cargo-gtm/references/cost-discipline.md).
### Adding a card
A workspace holds exactly one card. `update-payment-method` sets it, whether or not one is already on file, and takes the details three ways.
```bash
# Card details — no browser, nothing to hand off
cargo-ai billing subscription update-payment-method \
--card-number 4242424242424242 --card-exp 12/2030 --card-cvc 123
# Same, but keeps the number out of shell history and the process list
echo '{"number":"4242424242424242","expMonth":12,"expYear":2030,"cvc":"123"}' \
| cargo-ai billing subscription update-payment-method --card-stdin
# No card details — prints a Stripe-hosted form URL and waits for the card to land
cargo-ai billing subscription update-payment-method
```
**Prefer `--card-stdin`.** Anything passed as a flag is visible in shell history and to any process that can read the process list. Card details go from your machine straight to Stripe in exchange for a token; they never reach the Cargo API, and no output prints them.
**Never invent card details, and never reuse a number from elsewhere in the conversation.** Ask the user for them, or use the no-argument form and hand them the URL.
The no-argument form is the fallback when you have no details to submit: it prints a URL that opens directly on the card form, then polls until the card changes (`--timeout`, `--poll-interval`, `--no-open`). Relay that URL to the user — it works over SSH and in sandboxes.
Either way the card is verified against the issuer before it becomes the default, so a card that cannot be charged fails here rather than silently at the next renewal.
| Failure | What it means | What to do |
|---|---|---|
| `cardDeclined` + `declineCode` | The issuer refused the verification | Read `declineCode`. On a spend-limited virtual card, `insufficient_funds` or a limit code means the budget or merchant restrictions rule us out — ask the cardholder to raise it |
| `authenticationRequired` | The card wants 3-D Secure, which needs the cardholder present | Re-run with no arguments and hand the user the hosted-form URL |
| `paymentMethodNotFound` | The details did not resolve to a usable card | Re-check the number and expiry with the user |
Card updates are rate-limited to **10 per hour per workspace** (shared with setup intents). Retrying a declined card burns that budget — fix the cause rather than looping.
## Help
Every command supports `--help`:
```bash
cargo-ai billing usage get-metrics --help
cargo-ai billing subscription get --help
cargo-ai billing subscription get-invoices --help
```