Configuration#
This page lists every key you can set in lockpin.json, the config file Lockpin reads at start,
and the environment variables Lockpin reads. It is for anyone who runs Lockpin with settings other
than the defaults.
The config file#
lockpin init writes lockpin.json, and lockpin -config lockpin.json reads it.
lockpin init -schema prints every key the file may set. The file has three fields:
Field |
What it holds |
|---|---|
|
The providers you use, which |
|
Any of the keys in the key table, each named as the flag is, without the dash. |
|
Budgets per project, each with |
{
"providers": ["anthropic", "openai"],
"flags": {
"listen": "127.0.0.1:8787",
"default-budget": 2.5,
"compact": true,
"ask-at-cap": "5m"
}
}
Order of precedence#
A flag given on the command line.
The config file.
The default in the key table.
A signed machine policy sets floors that all of these can only tighten. Run lockpin policy show
to see the settings in force and where each one comes from (see Signed policy).
Checks#
A key that is not in the table is an error naming the nearest key that is. Every problem is
reported at once, with the key and what it accepts, both when Lockpin starts and by
lockpin doctor -config lockpin.json.
lockpin doctor -config lockpin.json
Secrets stay out of the file#
Provider keys stay in environment variables (lockpin providers lists them). A value that looks
like an API key, a token, a URL with a password or a Slack, Teams, Discord or ntfy.sh webhook URL is
refused. Give alert destinations in the LOCKPIN_ALERT_* environment variables instead (see
Environment variables).
Note
Automatic price updates from the signed price feed are not set here: the machine’s signed policy
turns them on (price_feed, off by default), and only the machine policy can choose the feed or the
keys it must be signed by. lockpin prices update applies the feed by hand. The prices-url key
below is the older, unsigned refresh. See Prices and the price feed.
Value types#
Type |
Accepts |
|---|---|
|
|
|
A whole number |
|
A number (USD or a percent) |
|
A string such as |
|
A string |
Keys#
Each key is also a flag of lockpin with a dash in front (default-budget is -default-budget).
Some keys change what the model sees; the table says so.
Budgets, caps and approvals#
Key |
Type |
Default |
Meaning |
|---|---|---|---|
|
number |
|
Budget in USD for tasks that set none. |
|
number |
|
The most every task on this machine may spend together per UTC day, in USD, whatever task or project a call names (solo mode; team keys have |
|
duration |
|
When a call would pass its task’s budget while the meter (or VS Code) is open, hold it this long and ask there whether to allow it. With nobody watching, or no answer in time, it is refused. |
|
bool |
|
Hold calls at the cap for |
|
bool |
|
Also ask about held calls in Slack, Teams and ntfy (the |
|
number |
|
How far, in percent of its budget, a task’s budget may be raised without the meter page (its control token), once per task per day; anyone may use it, an agent too. Beyond it, and to remove a cap, needs the meter page. |
|
bool |
|
Team mode: serve the held calls on the |
|
string |
none |
With |
|
bool |
|
Team mode: let |
|
bool |
|
Charge each call to its project as well as its task: the repository its agent works in (from Claude Code’s and Codex’s working folder, |
|
bool |
|
Charge an agent’s call that names no task (no |
|
bool |
|
Charge a Claude Code or Codex call that names no task to its session, as task |
|
bool |
|
Degrade before refusing: once a task has spent |
|
number |
|
The percent of a task’s budget, spent or in flight, at which |
|
bool |
|
Give capped calls that set no output limit one, so the cap holds for them too: |
|
int |
|
Largest output limit |
|
int |
|
Output tokens reserved when a request sets no limit and the model’s maximum output is unknown. |
|
string |
|
|
|
bool |
|
Charge failed calls their input cost (Meta can bill them). |
|
number |
|
Circuit breaker: refuse a task or key (429) that is charged more than this in |
|
duration |
|
How far back the circuit breaker counts spend. |
|
duration |
|
How long a tripped task or key is refused. |
|
string |
|
What the circuit breaker watches: |
|
string |
none |
JSON file mapping a model (or |
|
string |
|
When Lockpin’s own ledger file or keys file fails: |
Alerts and digest#
Key |
Type |
Default |
Meaning |
|---|---|---|---|
|
number |
|
Alert when spend reaches this percent of a task budget or key limit, once per period. |
|
string |
|
Warn when a task has spent these percents of its budget, once each: an alert and the |
|
string |
|
Slack incoming webhook URL for alerts. |
|
string |
|
Microsoft Teams Workflows webhook URL for alerts (“Post to a channel when a webhook request is received”). |
|
string |
|
ntfy topic URL for alerts, such as |
|
string |
|
URL that gets every alert as JSON. |
|
number |
|
Alert when drift tracking flags wasted or lost work costing at least this many USD. |
|
number |
|
Alert when a task’s, key’s or user’s spend today (UTC) reaches this many times its usual day (the median of its days with spend in the last 14; it needs 3), once per day. |
|
number |
|
Spike alerts only for days of at least this many USD, so small days never alert. |
|
bool |
|
Alert when a task repeats the same tool call with the same result 3 times. While the meter or VS Code is open, also hold the call and ask there whether to continue (for up to |
|
string |
|
When to post the weekly digest to the alert destinations, as a weekday and time on this machine. |
|
string |
|
The relay |
Network, ledger and listener#
Key |
Type |
Default |
Meaning |
|---|---|---|---|
|
string |
|
Address to listen on. Keep it on localhost unless |
|
string |
none |
Serve the meter and the breaker API on this address instead of |
|
string |
none |
Comma-separated host names the meter, and outside team mode the model routes, also answer to, besides localhost, IP addresses and the |
|
bool |
|
Open the meter in your browser once Lockpin is running (the setup page until the first call). If Lockpin is already running on |
|
string |
|
File that keeps spend across restarts. |
|
string |
|
When the ledger file is flushed to disk: |
|
string |
none |
Folder to keep writing the ledger to as JSON Lines, for the machine’s log agent (Splunk, Sentinel, Elastic, Datadog) to collect. Off when empty. It reads the ledger file off the call path and never changes a decision. |
|
string |
none |
PEM file of extra root certificates (a corporate TLS-inspection root) trusted in addition to the system store for every outbound connection. |
|
string |
|
Meta Model API base URL. |
|
int |
|
Tries per call on 429, 5xx and connection errors, first included. |
|
duration |
|
Wait before the first retry; doubles each time, with jitter. |
|
duration |
|
Longest wait between retries. |
|
duration |
|
Longest Retry-After to wait out. A provider that asks for more gets its reply passed to the client. |
|
string |
none |
Comma-separated paths under a provider’s |
|
bool |
|
Read Helicone’s request headers ( |
|
bool |
|
Log every request. |
Prices#
Key |
Type |
Default |
Meaning |
|---|---|---|---|
|
string |
none |
Catalog file(s), comma-separated and merged in order, with extra or changed providers and model prices (see |
|
string |
none |
HTTPS URL of an unsigned catalog to fetch into the first |
|
duration |
|
How often |
|
number |
|
A fetched catalog that lowers a price by more than this percent, or changes where calls go, is refused ( |
|
string |
none |
Price a model the catalog does not know at this USD per 1M tokens, |
|
bool |
|
Send capped calls that use a tool fee or tier Lockpin cannot price, at the standard price, instead of refusing them with 400. |
|
string |
none |
JSON file mapping Azure OpenAI deployment names to the models they run ( |
|
bool |
|
Say when a task would have cost less on its model’s cheaper step in the catalog, priced from its own calls, in the meter’s task API and |
Savings and caching#
Key |
Type |
Default |
Meaning |
|---|---|---|---|
|
bool |
|
Add |
|
bool |
|
Turn on Anthropic’s prompt cache for calls that mark none, when the task’s last call was under 5 minutes ago. |
|
string |
|
Lifetime of Anthropic calls’ prompt cache: |
|
bool |
|
Mark the system prompt of Anthropic calls that mark the cache elsewhere but not there, so trimmed or edited history keeps it cached. |
|
bool |
|
Let each Anthropic task decide for itself, from its own pauses and context, whether the 1-hour cache and keep-alive pay, with the arithmetic in |
|
duration |
|
Keep an idle task’s 1-hour Anthropic cache warm for this long after its last call (e.g. |
|
duration |
|
How long Meta’s prompt cache survives idle. |
|
bool |
|
Keep each request’s cacheable prefix the same call to call, on every provider: tools in one order and format, the system prompt’s whitespace fixed, its per-call lines (a date, a time, an id) moved to its end. Per request: |
|
bool |
|
Trim old tool results when it pays: never the newest |
|
int |
|
Most recent tool results never trimmed ( |
|
int |
|
Smallest worthwhile trim in tokens, so history is not trimmed a little every turn. |
|
string |
none |
Comma-separated tool names whose results are never trimmed. |
|
int |
|
Prompt size in tokens at which your agent summarises its own history (Codex, Claude Code); trimming stops there so the agent still does. |
|
bool |
|
Replace an exact repeat of earlier tool output with a one-line pointer to the copy still in the history; in batches every 3 calls, never in the newest 3 turns. Needs |
|
bool |
|
Replace an old read of a file that a later call edited with a one-line note; in batches every 3 calls, never in the newest 3 turns. Needs |
|
bool |
|
Add one line at the very end of each request of a task that has a budget, with the budget left and about how many more calls it pays for, so the agent can wrap up before the cap refuses it. Changes what the model sees. Per request: |
|
bool |
|
When a conversation starts over in a task (a |
|
string |
|
The pause and calls-per-task tables Lockpin keeps from its ledger ( |
|
string |
|
The learned pause model |
|
string |
none |
A/B experiments on the savings switches, such as |
Drift tracking#
Key |
Type |
Default |
Meaning |
|---|---|---|---|
|
string |
none |
Project folder to snapshot on every model call, to catch recreated, reverted, repeated and lost work. Empty: off. |
|
string |
none |
Goal file in the project to measure steps against, e.g. |
|
string |
none |
Checklist file in the project to follow, e.g. |
|
bool |
|
Add project notes (earlier sessions, removed code, warnings, plan) to the model’s instructions. Changes what the model sees. |
|
duration |
|
Idle time after which a task’s next call starts a new session. |
|
string |
none |
Where drift snapshots and the journal are kept (default: a folder in your user cache). |
Team mode#
Key |
Type |
Default |
Meaning |
|---|---|---|---|
|
string |
none |
Team mode: require a Lockpin key from this file on every call (see |
|
bool |
|
Team mode: a call’s |
|
int |
|
Team mode: keep the last prompt each person types, on this server only, for this many days (gzip, mode 0600; admins read them in the meter, members their own). Tell your team first. |
|
string |
none |
Folder |
|
string |
none |
Team mode: also accept spend capabilities ( |
|
string |
none |
With |
|
string |
none |
With |
|
bool |
|
With |
|
bool |
|
Accept keys made in the hosted dashboard (pushed as hashes; needs |
|
number |
|
USD a month a dashboard-made key may spend on this machine, whatever the dashboard set. |
Reporting and policy#
Key |
Type |
Default |
Meaning |
|---|---|---|---|
|
string |
|
Optional reporting: |
|
string |
|
Maximum detail: |
|
string |
none |
File containing JSON |
|
string |
|
Ingest base URL. |
|
string |
none |
Folder of the signed policy file and its pinned keys (default: |
|
bool |
|
While no signed machine policy is in force, refuse every metered call ( |
|
string |
none |
The per-user signed policy file, verified against the same pinned keys (default: |
Recording#
Key |
Type |
Default |
Meaning |
|---|---|---|---|
|
string |
none |
Write every model call to cassettes in this folder, one file per task, known key and token patterns removed, for |
|
duration |
|
With |
|
int |
|
With |
Warning
Cassettes hold prompts and code, so keep the -record folder private (it gets a .gitignore). In
team mode it records everyone’s prompts: tell your team first. Every entry holds the whole prompt,
so a long session’s cassette grows quickly (tens to hundreds of MB). Turn -record on for the
sessions you want to replay, not permanently, or cap it with -record-max-mb and -record-for.
Environment variables#
Variable |
What it does |
|---|---|
|
Changes the data folder where the service keeps its ledger (see Command reference). |
|
Extra root certificates (PEM) to trust, read when |
|
Slack incoming webhook URL for alerts. |
|
Microsoft Teams Workflows webhook URL for alerts. |
|
ntfy topic URL for alerts. |
|
URL that gets every alert as JSON. |
|
The approval webhook for held calls; setting it turns on |
|
The reporting token, instead of a |
|
Azure OpenAI deployment names mapped to the models they run; |
|
|
|
|
|
|
|
|
Provider API keys are read from each provider’s own key variable. lockpin providers lists which
variable each provider uses and whether it is set.