Admin API

Platform admins manage the model catalog (prices, capabilities, strengths) and custom providers (whole OpenAI-compatible vendors) at runtime. Every write takes effect on the next request — no redeploy. The web UI at /shimmy/admin drives these endpoints; they are also callable directly. A daily catalog sync keeps the catalog current without hand edits.

Model catalog

The catalog is the price-and-capability source of record. Routing, tiers and the savings meter all read from it; an edit reprices the ladder live.

RoutePurpose
GET /v1/admin/catalogEvery model with its full profile
PUT /v1/admin/catalog/:modelCreate or update one model
DELETE /v1/admin/catalog/:modelRemove a model
POST /v1/admin/catalog/:model/disabledToggle routing off without deleting the row
POST /v1/admin/catalog/syncRun the catalog sync now; ?dry_run=1 returns the diff without writing
GET /v1/admin/catalog/sync/logThe most recent sync changes

A model profile:

{
  "model": "kimi-k3",
  "provider": "moonshot",
  "input_per_mtok": 0.15,
  "output_per_mtok": 0.60,
  "cached_input_per_mtok": 0.04,
  "cache_write_multiplier": 1.25,
  "input_modalities": ["text", "image"],
  "output_modalities": ["text"],
  "tools": "full",
  "structured_outputs": true,
  "reasoning_efforts": [],
  "context_length": 200000,
  "max_output_tokens": 8192,
  "search_only": false,
  "moderation_only": false,
  "strengths": { "code": 2, "reasoning": 2 },
  "disabled": false
}

Disable without deleting — keeps the row and its accumulated evidence, just drops it from routing:

curl -X POST https://rfa-labs.com/v1/admin/catalog/kimi-k3/disabled 
  -H "Authorization: Bearer $ADMIN_KEY" 
  -H "Content-Type: application/json" 
  -d '{ "disabled": true }'

The catalog sync

Once a day (CATALOG_SYNC_INTERVAL_HOURS, default 24; 0 turns it off), one replica reads what every configured host offers and charges, then applies the difference:

  • Sources. Each host is the source for its own models and prices. Ollama Cloud’s live list and per-model prices come from ollama.com, at the Peak rate. Every other host lists its models at its own /models, and its price, context window and supported parameters come from OpenRouter’s per-host endpoints, which pass each host’s price through. models.dev fills any gaps. Artificial Analysis supplies benchmark scores.
  • Adds a model a configured host serves, but only with a published price and context window.
  • Corrects facts (context window, output cap, input modalities, tool and structured-output support) on every row, hand-edited ones included.
  • Reprices rows that weren’t hand-edited. A hand-set price stays.
  • Removes a model its host retired or stopped listing. For OpenAI and Anthropic it also removes models more than CATALOG_SYNC_MAX_AGE_DAYS old (default 180), keeping the newest model of each tier. A model that a Settled Step, a routing pin or a configured default still uses is kept and flagged instead, and so is a hand-entered row.

Custom providers

Register any OpenAI-compatible vendor (Moonshot, DeepSeek, Groq, …) at runtime. Models added under it route immediately and join the cross-vendor failover chain.

RoutePurpose
GET /v1/admin/providersRegistered vendors (key_set, never the key itself)
PUT /v1/admin/providers/:nameRegister or update a vendor
DELETE /v1/admin/providers/:nameRemove a vendor
POST /v1/admin/providers/:name/testA live call confirming the base URL + key work

Register a vendor — the name is a lowercase id you choose, the base URL must include the vendor’s version suffix, and the key is encrypted at rest and never returned:

curl -X PUT https://rfa-labs.com/v1/admin/providers/moonshot 
  -H "Authorization: Bearer $ADMIN_KEY" 
  -H "Content-Type: application/json" 
  -d '{
    "base_url": "https://api.moonshot.ai/v1",
    "api_key": "sk-vendor-…",
    "enabled": true
  }'

Then confirm it works before routing real traffic:

curl -X POST https://rfa-labs.com/v1/admin/providers/moonshot/test 
  -H "Authorization: Bearer $ADMIN_KEY"

Next