CLI
Inspect a catalog, debug an entitlement, seed a sandbox and move its clock.
Command line tools for Base316. Answers the questions that come up over and over while integrating: which environment am I pointed at, why was this entitlement refused, did that usage event land — and, in a sandbox, what happens next month.
npx @base316/cli login
npx @base316/cli init
npx @base316/cli whoamiGetting started
These need no key — they are how a directory gets one.
login [--no-wait] | Sign in as yourself by approving a code in the browser |
init [--project <name>] [--workspace <slug>] [--env-file <path>] [--force] | Create or pick a project and write its sandbox keys to .env |
logout | Sign out, revoking this machine's session on the server |
login --no-wait prints the link and code and exits, for an agent that only
sees output once a command finishes; a second login waits for the approval.
See Build with an agent for the whole flow.
Every other command reads BASE316_SECRET_KEY from the environment, or from
.env.local / .env in the current directory when it is not set — so after
init, nothing needs exporting. An exported value always wins over the file.
Commands
Catalog and accounts
whoami | Which project and environment this key points at |
plans · features · products | The catalog |
customers · subscriptions · invoices | Accounts and what they owe |
organizations [parent] | Tenants, or the clients one parent manages |
billed <customer> | The accounts a customer pays for, and their usage |
refunds [invoice] | Refunds, and whether each went through |
invoice:pdf <invoice> [file] | Download an invoice as a PDF |
phases <subscription> | What is scheduled, and what already applied |
price-overrides <subscription> | A subscription's custom prices, beside the ones replaced |
api-resources | The protected APIs, and the scopes each declares |
Entitlements
check <customer> <feature> | Whether a customer is entitled, and why not |
entitlements <customer> | Every feature at once, allowed or denied, and why |
Previews — nothing changes
upcoming <subscription> | The next invoice — nothing is raised |
quantity:preview <subscription> <n> | What changing the quantity would charge |
plan-preview <subscription> <version> | A plan change, now and at period end |
billing-anchor <subscription> <day|none> | What moving the billing day would charge |
plans:outdated [plan] | Subscriptions behind their plan's newest version |
plans:migrate-preview <plan> <version> [timing] | What moving those subscribers onto a version would do |
Writes
usage <customer> <event> | Record one event, to prove metering works |
seed [--reset] | Fill a sandbox with a catalog, customers and usage |
clock:advance <iso-date> | Move a sandbox's clock forward and run the billing sweeps |
api-resource:create <name> <audience> | Declare an API so tokens can be issued for it |
api-scope:add <resourceId> <scope> [feature] | Declare a scope, optionally gated on a feature |
replay <eventId> | Queue a past webhook event for delivery again |
Webhooks
listen <url> [--type <event>] | Forward this environment's events to a local URL, as a webhook would |
A customer can be named by Base316 id (cus_…) or by your own id — the prefix
decides which.
Options
--json | Print the raw API response, for piping into jq |
--live | Allow a write against a live key |
--help | The command list |
Writes are guarded on a live key
Every command marked as a write is refused on a live key unless --live is
passed, before any request is made:
$ base316 usage cus_abc123 api_call
Refused: `usage` would change live data.
This key is a live key. Re-run with --live if you mean it, or export a sandbox
key instead.A CLI is run from shell history and from scripts, and the gap between seeding a sandbox and metering ten thousand events against production is one environment variable somebody forgot to change. The band is read from the key's own prefix, so the check cannot fail open when the network does.
Environment
BASE316_SECRET_KEY | A secret key (b316_sk_…), or read from .env.local / .env. A publishable key is refused — it cannot read customers or invoices. |
BASE316_API_URL | Defaults to https://api.base316.com. Point it at http://localhost:3110 for a local stack. |
BASE316_APP_URL | The dashboard login and init talk to. Defaults to https://app.base316.com. |
BASE316_CONFIG_DIR | Where login keeps its session. Defaults to ~/.config/base316. |
Debugging an entitlement
The command worth knowing about:
$ base316 check cus_abc123 api_calls
DENIED
Reason USAGE_LIMIT_EXCEEDED
Limit 1000
Used 1000
Remaining 0A bare "false" sends you to the dashboard. A reason sends you to the fix.

