Credits and commits

Complimentary grants, paid top-ups and ledger adjustments.

View .md

Goal

Three common balance changes on Acme Corp's active contract:

ChangeCommandMetronome call
Add or remove an amount on an existing balancemetro ledger-adjustment preflight --amount=<signed-int>manual ledger entry
Grant a new credit, or a complimentary commitmetro ledger-adjustment preflight --grant=credit or --grant=commitcontract edit, add_credits or add_commits
Remove a whole grantmetro ledger-adjustment preflight --archive-balance-id=<id>contract edit, archive

Every write carries a uniqueness_key, so a retry returns 409 instead of a second grant. See Credits & commits.

Preview

First, read the balances:

metro customer balances --ingest-alias=acme-corp --sandbox --only-nonzero --json

The output includes spendableNet: the net balance per credit type next to the sum of the balance list. If they disagree, metro warns with MTR-CREDIT-NET-001 and refuses additions for that credit type. Trust the net.

Then preflight the change. A $500 service credit for one year, as a new grant on a USD-cents credit type:

metro ledger-adjustment preflight --grant=credit --amount=50000 \
  --product-id=00000000-0000-4000-8000-000000000011 \
  --starting-at=2026-12-01T00:00:00.000Z --ending-before=2027-12-01T00:00:00.000Z \
  --reason="Service credit for the November outage" \
  --ingest-alias=acme-corp --sandbox --out=ledger.json

The credit type comes from metro catalog bind --sandbox --write, or pass --credit-type-id=; metro won't guess it. The amount is in that credit type's units. Name the grant with --grant-name=, and set --priority= to control drawdown order. --grant=commit adds a PREPAID commit with no invoice schedule: a complimentary commit.

Or an adjustment of an existing balance. Additions need a target: --contract-id= or --balance-id=. A removal picks the one balance that covers it, or asks you to choose.

metro ledger-adjustment preflight --amount=-2500 --reason="Correct double grant" \
  --ingest-alias=acme-corp --balance-id=00000000-0000-4000-8000-000000000008 \
  --sandbox --out=ledger.json

The preflight prints the diff, for example balance 00000000-0000-4000-8000-000000000008: 10000 -> 7500, the steps and the Payload hash.

Offline first, if you want

The complimentary-credit-grant and paid-credit-top-up shapes check a grant with no API call at all. This is real output:

metro plan template complimentary-credits --sandbox --out credit.json
metro validate --shape complimentary-credit-grant --file credit.json
metro credit preview --shape complimentary-credit-grant --file credit.json --sandbox
✓ Validation passed for complimentary-credit-grant.
Why: The input matches the reviewed shape rules and guardrails.

Preview built for complimentary-credit-grant on sandbox.
Payload hash: sha256:d96a502b2c89d69048dfd7aff170ea47e1b0af9f71e2c57905bf6718b8f43f6e
Actions: 1
Apply supported: no

Shapes don't apply. Use them to agree on the grant, then run the ledger-adjustment preflight above.

Confirm

Show the human the customer, the balance before and after (or the new grant's amount and dates), the reason and the hash. Then dry-run:

metro ledger-adjustment apply --file ledger.json --sandbox --confirm-hash sha256:...

Apply

metro mode write
metro ledger-adjustment apply --file ledger.json --sandbox --confirm-hash sha256:... \
  --apply --confirm-live-apply=I_UNDERSTAND_THIS_WILL_WRITE_LIVE_METRONOME_SANDBOX

On production: --prod --confirm-prod-apply=I_UNDERSTAND_BILLING_SIDE_EFFECTS, after the human's typed yes for this change.

Readback

metro re-reads the balances. The check depends on the mode:

Applied (sandbox).
Read-back (expected vs actual):
  ok   balance 00000000-0000-4000-8000-000000000008: expected 7500 actual 7500

A grant checks add_credits present with amount 50000 (or add_commits). An archive checks <balance id> archived. Any FAIL exits 3. Illustrative IDs; the format is exact.

On this page