Base 3:16
Getting started

Keys and environments

Sandbox and live, secret and publishable, and which mistake each one prevents.

Environments

Every project has a Sandbox and a Production environment. They are completely separate: separate customers, separate plans, separate invoices, separate number sequences. Nothing crosses between them.

A key belongs to exactly one environment, so the key decides which data you touch. There is no "environment" parameter to get wrong.

Two kinds of key

PrefixWhere it belongsWhat it can do
b316_sk_…Your server, onlyEverything the API offers
b316_pk_…A browserPublic catalog and sign-in flows

A publishable key cannot read customers, subscriptions or invoices. That is the point of it: it ships to a browser where anybody can read it, so it must not be able to enumerate your customers.

The band is in the key itself — b316_sk_sandbox_… versus b316_sk_live_… — so you can tell what you are pointed at without asking.

The mistake this prevents

Running a script against production while believing it is sandbox.

Both the CLI and the MCP server read the band from the key and refuse writes on a live key unless you say so explicitly:

$ base316 usage cus_abc123 api_call
Refused: recording 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.

The check is local — it reads the key's own prefix rather than asking the server — so it cannot fail open when the network does.

Scoped keys

A secret key can be issued with permissions, so it can do one job and no other — a sales tool that sends agreements has no business reading invoices. Today the scope that exists is agreements:

PermissionAllows
agreement.readGET /v1/agreements and everything under it
agreement.writeCreating, sending, resending, revoking and importing
agreement.*Both

A scoped key is refused, with KEY_PERMISSION_DENIED and the permission it needed in error.param, on every route its permissions do not name — it is fail-closed. A key issued without permissions is unrestricted, exactly as keys always were. Publishable keys cannot be scoped. Choose the scope when you issue the key under Keys.

Rotating a key

Create the new key first, deploy it, then revoke the old one. A revoked key stops working immediately, and its row is kept so audit history stays attributable rather than pointing at nothing.

Configuration

VariableMeaning
BASE316_SECRET_KEYYour server-side key
BASE316_API_URLDefaults to https://api.base316.com

The SDK reads both from the environment, so new Base316() with no arguments is usually right.

On this page