Log in

cargo-billing

All-time installs
6,661

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.

Other options

Summary

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.

Raw SKILL.md

15.8K bytes
---
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 [email protected]  # 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
```

Security audits

SnykFAIL
SocketPASS
Gen Agent Trust HubPASS