Ingram Cloud

Documentation

Credits & billing

Credits & billing

Credits are your organization's prepaid balance with Ingram Cloud — the money you pay us for platform usage. This is the opposite direction from Customers & metering, which is the money you bill your own customers; the two never share a page on purpose.

Credits are held at the organization level (one wallet pooled across all of your projects), not per project or per customer. Ingram Cloud is the merchant of record for these charges; your card is charged through Stripe.

Your wallet is held in your organization's billing currency — EUR by default, set from Stripe when you add a card. Every amount below (balance_cents, ledger entries, top-ups) is in that currency; format *_cents as minor units of it.

Start free: unlock €10

Running agents needs a verified card — the free trial is card-gated to keep fraud out, but adding a card costs nothing. Add one (Settings → Billing → Add a card) and €10 in credits unlocks immediately, no charge. Until a card is added, runs are refused with 402 card_required.

# Authorization: organization key (server-side only)
curl https://api.cloud.ingram.tech/v1/organization/billing/setup \
  -H "Authorization: Bearer $IC_ORG_TOKEN" \
  -H "IC-Api-Version: 2026-05-01" \
  -H "Content-Type: application/json" \
  -d '{ "return_url": "https://your.app/billing?setup={CHECKOUT_SESSION_ID}" }'
# → 201 { "url": "https://checkout.stripe.com/c/pay/cs_…" }

This is a no-charge Stripe setup session: the card is saved (and reused for top-ups and auto-reload), and the €10 welcome credit is granted once per organization, when the card verifies.

Buying credits

The console is the way in: Settings → Billing → Buy credits. Pick a preset (€20 / €100 / €500) or enter another amount, then pay by card inline — Stripe collects the card and billing address and computes any tax. Your balance updates the moment Stripe confirms the charge.

A Stripe customer record for your organization is created only on the first successful payment, and reused (with any saved card) on later top-ups.

Checking your balance

The balance lives on the organization surface, so it takes an organization key:

# Authorization: organization key (server-side only)
curl https://api.cloud.ingram.tech/v1/organization/billing/balance \
  -H "Authorization: Bearer $IC_ORG_TOKEN" \
  -H "IC-Api-Version: 2026-05-01"
# → 200 { "currency": "eur", "balance_cents": 10000,
#         "stripe_customer": true }

GET /v1/organization/billing/ledger returns the append-only ledger, newest first — each entry carries a signed amount_cents and a kind. Top-ups are positive kind:"topup"; usage debits are negative kind:"debit". Pass ?direction=credit to return only money-in rows (top-ups and grants) or ?direction=debit for only usage. The list is keyset-paginated like every other (?limit= up to 100, default 25; pass the returned next_cursor back as ?cursor= until has_more is false).

How usage draws down credits

Every run your agents make is metered and debited from the org wallet when it finishes. On an Ingram-hosted key the charge is the run's provider cost (priced from the model price book and converted into your billing currency) times your organization's margin (the platform markup; 20% by default, set per organization). On a key of your own it is the platform fee alone — see Your own keys. The wallet is one pool across all your projects; which project drew how much is on each debit and summarized by the per-project endpoint below. Usage you've already started always finishes — the balance can dip slightly negative on an in-flight run; the gate below catches the next one.

Your own keys

The wallet recovers the provider cost only when we paid it. When a turn runs on a key of yours — your organization's BYOK key or a smith's own end-user key — the provider billed that account directly, so the wallet is charged the platform fee only (cost × (margin − 1), i.e. 20% of list cost at the default margin, not 120%). This is what "no model markup" means: bring your own key and you never pay us for the tokens, only for the platform.

Ingram-hosted keys are our spend, so those turns draw the full cost × margin.

The run's metered usage always records the full token count and list cost for attribution; only the wallet draw changes. Each debit's metadata carries key_source (smith / byok / hosted) so a fee-only draw is auditable.

Per-project spend

One wallet funds every project, so the org view is "which project is spending it":

# Authorization: organization key (server-side only)
curl "https://api.cloud.ingram.tech/v1/organization/billing/usage?period=2026-06" \
  -H "Authorization: Bearer $IC_ORG_TOKEN" \
  -H "IC-Api-Version: 2026-05-01"
# → 200 { "period": "2026-06", "currency": "eur", "total_drawn_cents": 4210,
#         "total_tokens": 512000, "projects": [ { "project_id": "proj_…",
#           "name": "Acme", "drawn_cents": 4210, "tokens": 512000,
#           "budget_limit": 100, "budget_action": "block" } ] }

drawn_cents is the wallet draw (the platform margin is already in it — this is your cost, not the raw provider cost); tokens is what the project's runs consumed that period. period defaults to the current calendar month (UTC). budget_limit is the project's funding cap — a tenant-scope cost budget set on that project — or null when the project draws freely from the org wallet. Without a budget a project is bounded only by the org's overall balance; with a block budget it stops at its own limit even while the wallet still has funds.

For the trend rather than the total — to catch a recent spike or drop in one project — ask for the daily draw over a rolling window:

# Authorization: organization key (server-side only)
curl "https://api.cloud.ingram.tech/v1/organization/billing/usage/series?days=30" \
  -H "Authorization: Bearer $IC_ORG_TOKEN" \
  -H "IC-Api-Version: 2026-05-01"
# → 200 { "currency": "eur", "from": "2026-06-13", "to": "2026-07-12",
#         "projects": [ { "project_id": "proj_…", "name": "Acme" } ],
#         "points": [ { "day": "2026-07-11", "project_id": "proj_…",
#           "drawn_cents": 320 } ] }

days is the rolling window ending today (UTC), 1–365, default 30. points are sparse — a day/project with no draw is simply absent, so treat a missing cell as zero. projects lists those with any draw in the window, ranked by total.

When runs are refused

Two prepaid gates, both at run creation:

  • 402 card_required — no verified card yet. Add one to unlock €10 free (above).
  • 402 insufficient_credits — the wallet is empty; a credit.exhausted event fires. If auto-reload (below) is on, it charges your saved card first and the run proceeds when the top-up clears.

A run already in flight is never interrupted. When the wallet runs out, the organization's owners and admins get one email — the next one only after the balance is topped up and depleted again.

Starting a top-up programmatically

The console uses a Stripe-hosted Checkout Session under the hood. If you build your own top-up UI, mint the session and redirect the buyer to its URL:

# Authorization: organization key (server-side only)
curl https://api.cloud.ingram.tech/v1/organization/billing/checkout \
  -H "Authorization: Bearer $IC_ORG_TOKEN" \
  -H "IC-Api-Version: 2026-05-01" \
  -H "Content-Type: application/json" \
  -d '{ "amount_cents": 10000,
        "return_url": "https://your.app/billing?topup={CHECKOUT_SESSION_ID}" }'
# → 201 { "url": "https://checkout.stripe.com/c/pay/cs_…" }

Send the browser to url (Stripe's hosted checkout). Credits are applied when Stripe confirms the payment (via our webhook), not when the session is created — so a balance reflects a top-up a moment after the customer finishes paying.

Redeeming a credit code

If you've been given a credit code, redeem it from the Redemption code box on the billing page, or call the API. Codes are one-time-use and matched case-insensitively; the credit lands in your wallet immediately as a kind:"redemption" ledger entry.

# Authorization: organization key (server-side only)
curl https://api.cloud.ingram.tech/v1/organization/billing/redeem \
  -H "Authorization: Bearer $IC_ORG_TOKEN" \
  -H "IC-Api-Version: 2026-05-01" \
  -H "Content-Type: application/json" \
  -d '{ "code": "WELCOME10" }'
# → 200 { "amount_cents": 1000, "currency": "eur" }

amount_cents is the amount credited in your wallet's currency (a code in another currency is converted on the way in). An unknown or malformed code returns 422 invalid_code; one already used returns 409 code_already_redeemed.

Auto-reload

Auto-reload keeps your balance from running dry without you watching it: when the balance falls below a threshold, your saved card is charged for a fixed reload amount. It's off by default; the threshold defaults to €10 (the console's low-balance line, so it fires before the wallet empties) and the amount is yours to set. The first top-up saves your card, so auto-reload only works once you've bought credits at least once.

# Authorization: organization key (server-side only)
curl -X PUT https://api.cloud.ingram.tech/v1/organization/billing/autoreload \
  -H "Authorization: Bearer $IC_ORG_TOKEN" \
  -H "IC-Api-Version: 2026-05-01" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "threshold_cents": 1000, "amount_cents": 10000 }'
# → 200 { "enabled": true, "threshold_cents": 1000, "amount_cents": 10000 }

GET /v1/organization/billing/autoreload reads the current settings back. Once usage debits draw your balance down past the threshold, auto-reload tops it back up off-session. You can also top up from the saved card on demand — POST /v1/organization/billing/reload charges it now (amount_cents optional, defaults to your configured reload amount):

# Authorization: organization key (server-side only)
curl -X POST https://api.cloud.ingram.tech/v1/organization/billing/reload \
  -H "Authorization: Bearer $IC_ORG_TOKEN" \
  -H "IC-Api-Version: 2026-05-01" \
  -H "Content-Type: application/json" \
  -d '{ "amount_cents": 5000 }'
# → 200 { "credited": true, "payment_status": "succeeded" }

A reload returns 409 no_saved_card if no card has been saved yet.

Managing billing & invoices

GET /v1/organization/billing/portal mints a Stripe billing portal session — manage your billing address and VAT id, update the saved card, and download invoice history. Pass a return_url Stripe sends the user back to:

# Authorization: organization key (server-side only)
curl "https://api.cloud.ingram.tech/v1/organization/billing/portal?return_url=https://your.app/billing" \
  -H "Authorization: Bearer $IC_ORG_TOKEN" \
  -H "IC-Api-Version: 2026-05-01"
# → 200 { "url": "https://billing.stripe.com/p/session/…" }

The portal needs an existing Stripe customer, so it returns 404 no_customer until your first top-up has created one.

In the console

Organization overview (from the organization menu in the workspace switcher) is the at-a-glance, cross-project view: this month's combined spend, tokens, and credits remaining, plus a spend-by-project breakdown that ranks each project's draw against its funding cap (toggle it to rank by tokens instead) and a spend-over-time chart — daily draw per project over a 7/30/90-day window, for spotting a recent spike or drop. It reads the GET /v1/organization/billing/usage and …/usage/series endpoints above.

Settings → Billing shows your current balance with Add a card (unlock €10 free, shown until a card is on file), Buy credits, Auto-reload (with a Reload now button), Manage billing & invoices (the Stripe portal), and the same per-project breakdown. Both sit apart from Observe → Usage & cost (the single-project provider-cost view and per-project budgets) and Build → End users (what you bill others).