Reference

Everything radarmodel-ai 0.1 does, in one page. The README on GitHub says the same in the repository.

Commands

radarmodel-ai init  [-config FILE]           write a starter config
radarmodel-ai check [-config FILE] [flags]   scan once, compare, report
radarmodel-ai watch [-config FILE] [flags]   scan every interval until stopped
radarmodel-ai show  [-config FILE] SOURCE    list the stored models of a source
radarmodel-ai version

The config is radarmodel.json in the current folder, or the file in $RADARMODEL_CONFIG, or -config FILE.

Flags for check and watch:

Flag What it does
-min info|warning|breaking Lowest severity shown at the terminal. Warning by default; the rest is counted
-json Print the report as JSON
-no-alerts Skip webhook, Slack and email
-dry-run check only: compare, but keep the stored snapshots

Exit codes

Code Meaning
0 Scanned, nothing breaking
1 At least one breaking change
2 A provider couldn’t be scanned, another run holds the state folder, or the config is wrong

Breaking wins: a run with a breaking change and a failed provider exits 1, and the report shows both.

Configuration

{
  "interval": "1h",
  "timeout": "30s",
  "min_fraction": 0.5,
  "confirm_removals": true,
  "state_dir": ".radarmodel",
  "providers": [
    {"type": "openai"},
    {"type": "anthropic"},
    {"type": "google"},
    {"type": "openrouter"},
    {"type": "openai", "name": "proxy", "base_url": "https://llm-proxy.example.com", "api_key_env": "PROXY_KEY"}
  ],
  "watch": ["openai:gpt-4o", "anthropic:claude-sonnet-4-5", "google:gemini-2.5-flash", "openrouter:anthropic/*", "proxy:gpt-4o"],
  "alerts": {
    "min_severity": "warning",
    "webhook": {"url_env": "RADAR_WEBHOOK_URL"},
    "slack": {"url_env": "SLACK_WEBHOOK_URL"},
    "email": {"host": "smtp.example.com", "port": 587, "from": "radar@example.com",
              "to": ["ops@example.com"], "username_env": "SMTP_USER", "password_env": "SMTP_PASS"}
  }
}
Setting Default What it does
providers none The lists to read. type is openai, anthropic, google or openrouter
providers[].name the type Name used in reports, watch entries and file names. Two entries of one type need different names
providers[].base_url the provider’s API A proxy or compatible endpoint. file:// reads saved answers from disk (Linux and macOS)
providers[].api_key_env OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY Variable holding the key. OpenRouter needs none
watch none Models your app calls, as source:model. * matches anything, slashes included; a source of * means every provider
interval 1h Time between scans in watch mode. At least 1m
timeout 30s Limit for one HTTP request
min_fraction 0.5 A list with fewer than this share of the last one’s models is a failed scan. 0 turns it off
confirm_removals true A watched removal is breaking only when a second scan agrees. false reports it on the first
state_dir .radarmodel Where snapshots are kept, relative to the config file
alerts.min_severity warning Lowest severity that sends an alert. A failed scan always sends one
alerts.webhook none url_env, or url for a URL with no token. Gets the JSON report
alerts.slack none url_env naming the incoming-webhook URL. Gets a text summary
alerts.email none host, port (587), from, to, and username_env and password_env if the server needs them. STARTTLS when offered

Unknown fields are errors, and so are watch entries naming a source that isn’t configured, source names that differ only in case or punctuation, and secret variables that are named but not set.

What counts as what

Only watched models can be breaking or warnings. Every other change is info.

Change to a watched model Severity
Gone from the list, on two scans in a row breaking
Gone from the list on one scan warning
Context or output limit went down breaking
Lifecycle became retired (Anthropic) breaking
Lifecycle left active, such as deprecated (Anthropic) warning
Got or changed a retirement date (Anthropic, OpenRouter) warning
A limit is no longer published warning
Price went up, or a price appeared or vanished warning
Lost a supported method (Google) warning
Named in watch but not in the list warning, every run
New models, price cuts, bigger limits, name changes info

When a watched model disappears and a model with the same display name appears in the same scan, the report adds “possibly renamed to …”.

What each provider shows

Provider What’s compared
OpenAI Model IDs and owner
Anthropic Display name, input and output limits, lifecycle, retirement date
Google Display name, version, input and output limits, supported methods
OpenRouter Name, context length, max output, input and output price per token, retirement date

What a failed scan is

A failed scan reports an error for that provider, changes nothing in its stored snapshot, and lets the other providers scan as usual. These are all failed scans:

  • an HTTP error. 408, 429 and 5xx get three attempts in all, honouring Retry-After up to 30 seconds
  • a body that isn’t valid JSON, is cut off, or has no model list
  • an empty list
  • a page of a paged list failing, or a paged answer where one page was expected
  • fewer models than min_fraction of the last list
  • a redirect to another host, refused so keys can’t follow it
  • a timeout

Files

state_dir holds latest/SOURCE.json, the snapshot the next scan compares with, and the last 50 snapshots in history/SOURCE/. Each file is written whole or not at all. A lock file keeps two runs from using the folder at once; one older than 30 minutes is taken to be left from a crash.