cargo-billing
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
Install
npx skills add https://github.com/getcargohq/cargo-skills/tree/main/cargo-billing
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install getcargohq-cargo-skills@llmmart
git clone https://github.com/getcargohq/cargo-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole getcargohq/cargo-skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Cargo CLI — Billing
Billing and credit management: pulling usage metrics, checking subscription status, viewing invoices, and managing credits.
See
references/response-shapes.mdfor full JSON response structures. Seereferences/troubleshooting.mdfor common errors and how to fix them. Seereferences/examples/usage-metrics.mdfor usage metric and subscription examples.
Bootstrap
Already signed in (cargo-ai whoami returns a workspace)? Skip to the next section.
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 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.
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
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:
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:
# 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:
# 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.
Usage metrics
Pull credit and usage data for any time range, optionally filtered and grouped.
# 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:
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:
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
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):
| 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 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.
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.
# 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:
cargo-ai billing usage get-metrics --help
cargo-ai billing subscription get --help
cargo-ai billing subscription get-invoices --help
Files (cargo-skills)
-
references
-
examples
-
usage-metrics.md 5.3 KB
# 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 ```
-
-
response-shapes.md 4.6 KB
# 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. -
troubleshooting.md 3.1 KB
# 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 792 B
{ "$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 15.4 KB
--- 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 ```
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.