The CLI infers the host from the key. From
0.2.0 on it resolves the host from the key prefix (sk_test_ → sandbox,
sk_live_ → production), so INFI_API_URL is only for deliberately pointing
somewhere else. Before 0.2.0 it was required in sandbox.The file
defineBilling / infi.billing.ts still work as aliases.
The file is loaded as ESM. The CLI imports the
.ts directly. If the project’s package.json has no
"type": "module", the load fails with “Cannot use import statement outside a
module”.Intents
Shortcuts that generate a sensible company file. They live in the CLI and in the file — the public provisioning endpoint does not acceptintent:
Commands
Plan grants
Each product may declaregrants[]:
on: "cycle"— credits when the period opens or renews (subscription/prepaid)on: "payment"— credits onpayment.confirmed(one-time packs)
meter is real: each meter has its own wallet. A grant on
tokens credits the tokens wallet, and
GET /metering/customers/{id}/wallet returns each balance:
creditsPerCycle still exists (but is legacy). It is still in the types and still honoured: the rule is grants[{ on: "cycle" }]
first, and creditsPerCycle as a fallback. So an old file does not break — but
write grants[] in new code, which is the only way to credit a specific meter or
to credit on: "payment".A Every
prepaid version needs a price to publish. Publishing a prepaid version requires a positive basePrice or a meter
price published on it. With neither, publish answers 422 and the product stays
in draft — chargeable by nobody.Which means a free tier (no monthly fee) works as long as the meter has a price,
which is what rates the wallet’s consumption:price is a meter rate: a fixed amount is not a price, it is the
version’s basePrice.Webhooks in the file
The company file’swebhooks[] is applied by sync — and in sandbox that hits
503 secret_store_unavailable, because a test tenant has no secret store. It is
not a syntax error in your file. See webhooks.