Control plane reference
The account’s API, typed, on shimmy.control — and the HTTP routes behind it.
Every route takes the Workflow’s sk-opt-… key as a bearer token, or the
dashboard’s session.
const workflows = await shimmy.control.workflows();
const calls = await shimmy.control.calls({ agent: workflowId, limit: 50 });
const graph = await shimmy.control.agentGraph(workflowId); Workflows and the Report
const workflows = await shimmy.control.workflows(); // Stage + progress
const report = await shimmy.control.report(id); // live; or report(id, 3)
const lock = await shimmy.control.lockfile(id); // shimmy.lock as JSON
const wallet = await shimmy.control.billing(); | Method | Route | Returns |
|---|---|---|
workflows() | GET /v1/workflows | Each Workflow: stage, steps_expected, steps_settled, ready |
report(id, version?) | GET /v1/workflows/:id/report[?version=N] | The live Report with its stage and newest version, or a stored version |
lockfile(id) | GET /v1/workflows/:id/report/lock | shimmy.lock, from the newest stored version |
recordings(id) | GET /v1/workflows/:id/recordings | Every Recording, as shimmy recordings pull writes them |
Routes without an SDK method, which the dashboard and CLI use:
| Route | |
|---|---|
POST /v1/workflows/:id/report/finalize | Store the Report as final now, settled or not |
GET /v1/workflows/:id/steps | The Step registry: when each Phase last saw each Step, and whether it’s expected |
PATCH /v1/workflows/:id/steps/:fingerprint | { "excluded": true } takes a Step out of the Expected Steps |
GET /v1/workflows/:id/steps/:fingerprint/calls[?model=] | The stored responses behind a Step’s Report entry |
GET /v1/workflows/:id/events[?days=] | Production events: drift, failover, resettled |
Workflow keys
A Workflow is created with its first key; calls made with a key belong to its Workflow.
| Method | Notes |
|---|---|
listAgents() | Every Workflow, with its call totals |
createAgent(name) | Creates a Workflow. The response carries the only copy of its key |
createAgentKey(id) | An additional key for a Workflow |
agentGraph(id) | The Workflow’s Steps as a graph, from its calls |
Calls
| Method | Returns |
|---|---|
calls({ agent, limit }) | Per-call detail: models, grades, cost, cache, guardrail findings |
activity({ limit }) | The raw metered timeline |
Billing
| Method | Route | |
|---|---|---|
billing() | GET /v1/billing | Wallet and Dev allowance balances, prices, auto top-up, subscriptions, the last 50 ledger entries |
POST /v1/billing/topup | { "amount_usd": 50 } → a Stripe Checkout URL | |
PUT /v1/billing/auto-topup | { "threshold_usd": 10, "amount_usd": 50 }; both null to turn it off | |
POST /v1/workflows/:id/subscription | Start managed Production for a Workflow | |
DELETE /v1/workflows/:id/subscription | Cancel at the end of the paid period |
savings() and statement() read the pre-Shimmy savings ledger and fee
statement; they’re kept for history.
Settings
| Method | Route | |
|---|---|---|
routingSettings() / setRoutingSettings() | /v1/settings/routing | Mode, allowed providers, tiebreak, ladders, advanced search |
captureSettings() / setCaptureSettings() | /v1/settings/capture | Content capture and retention outside Tuning |
guardSettings() / setGuardSettings() | /v1/settings/guard | PII redaction, injection policy |
GET /v1/settings/provider-keys | The providers you’ve stored keys for — never the keys | |
PUT/DELETE /v1/settings/provider-keys/:provider | { "key": "…" } — Production runs on these | |
GET/PUT /v1/settings/alerts | Email, webhook, spend cap — see alerts |
Routing writes are validated locally first — see config as code.
Custom agents
The custom agents RFA Labs builds for a customer are a separate product with
their own methods (listManagedAgents(), startRun(), getRun(), …) and their
own front door at /custom-agents. They are not part of Shimmy.
Unauthenticated
Signup is how you get a key, so these are standalone functions rather than methods on a class you cannot construct yet.
import { signup } from '@rfa-labs/shimmy';
// Creates the account and its first Workflow; api_key is shown once.
const { api_key } = await signup({ company: 'Acme', email: 'dev@acme.com' }); login() / logout() exist for browser session auth. Server-side integrations
authenticate with the sk-opt-… key on every request and never need them.
Errors
Every failure raises a typed error carrying status, endpoint, message and
the raw body. Payment errors are 402 with a type saying why: wallet_empty (Tuning, no Wallet and no stored keys), dev_allowance_exhausted, subscription_required (managed Production) and spend_cap_reached.