Management API
Configure your fallback providers from scripts and coding agents instead of the dashboard. Authenticate with a management key: a separate key type that can manage your account but cannot make inference calls. Your inference keys cannot call these endpoints.
1. Create a management key
In Settings → Management API Keys, create a key, choose its scopes (fallbacks:read, fallbacks:write, usage:read) and expiry, and copy it. It starts with rdm_ and is shown once. We store only a hash. Every call is rate-limited (60/min per key by default) and audit-logged with the key id, action and model ids, never your provider key.
export RD_MGMT_KEY=rdm_... # keep it out of your repoEndpoints
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /api/v1/management/fallbacks | fallbacks:read | List your fallbacks (keys masked) and the served model ids |
| GET | /api/v1/management/fallbacks/{model_id} | fallbacks:read | Get one fallback |
| PUT | /api/v1/management/fallbacks/{model_id} | fallbacks:write | Create or replace one fallback (idempotent) |
| POST | /api/v1/management/fallbacks/bulk | fallbacks:write | Set the same fallback for many models at once (idempotent, atomic) |
| DELETE | /api/v1/management/fallbacks/{model_id} | fallbacks:write | Remove one fallback |
| POST | /api/v1/management/fallbacks/test | fallbacks:write | Dry-run one 1-token request to the provider; returns ok/error |
| GET | /api/v1/management/usage/metrics?window=24h&model= | usage:read | Your requests, tokens, spend, cache-hit rate, TTFT p50/p90/p99, tok/s, error rate, failover share and fill-or-kill outcomes over 1h / 24h / 7d / 30d |
| GET | /api/v1/management/status | usage:read | Engine status (healthy / degraded / failing_over) and incidents from the past week |
{model_id} is one of our model ids (e.g. google/gemma-4-26B-A4B-it, any capitalization) or *. The request body fields are fallback_url (an https base URL), fallback_api_key, fallback_model (the provider's own id for the model) and is_active. Responses show the key only masked, e.g. ••••••••••••abcd.
Set an Inworld fallback for all Gemma models in one call
model_ids takes our model ids or glob patterns over them. fallback_models maps each of our models to the provider's id. Inworld uses Basic auth, so send its Basic (Base64) credential from platform.inworld.ai/api-keys with a Basic prefix.
curl -X POST https://inference.raindragon.ai/api/v1/management/fallbacks/bulk \
-H "Authorization: Bearer $RD_MGMT_KEY" -H "Content-Type: application/json" \
-d '{
"model_ids": ["google/gemma-*"],
"fallback_url": "https://api.inworld.ai/v1",
"fallback_api_key": "Basic '"$INWORLD_BASIC"'",
"fallback_models": {
"google/gemma-4-26B-A4B-it": "inworld/models/gemma-4-26b-a4b-it",
"google/gemma-4-31B-it": "inworld/models/gemma-4-31b-it"
}
}'
# -> {"results":[{"model_id":"google/gemma-4-26B-A4B-it","status":"created",...}, ...]}
# Run it again: every status is "unchanged".Check the Inworld model ids against Inworld's model list. A model with no entry in fallback_models uses fallback_model, or our own id if that is unset. If any entry is invalid, nothing is written.
One model, a catch-all default, test, delete
# upsert one model (201 created, then 200 "unchanged" on repeat)
curl -X PUT https://inference.raindragon.ai/api/v1/management/fallbacks/google/gemma-4-26B-A4B-it \
-H "Authorization: Bearer $RD_MGMT_KEY" -H "Content-Type: application/json" \
-d '{"fallback_url":"https://openrouter.ai/api/v1","fallback_api_key":"'"$OPENROUTER_KEY"'",
"fallback_model":"google/gemma-4-26b-a4b-it"}'
# default for every model without its own fallback, including models added later.
# It forwards each request's own model id, so it cannot set fallback_model.
curl -X PUT https://inference.raindragon.ai/api/v1/management/fallbacks/* \
-H "Authorization: Bearer $RD_MGMT_KEY" -H "Content-Type: application/json" \
-d '{"fallback_url":"https://openrouter.ai/api/v1","fallback_api_key":"'"$OPENROUTER_KEY"'"}'
# test the saved fallback: one max_tokens=1 request to your provider (billed by them)
curl -X POST https://inference.raindragon.ai/api/v1/management/fallbacks/test \
-H "Authorization: Bearer $RD_MGMT_KEY" -H "Content-Type: application/json" \
-d '{"model_id":"google/gemma-4-26B-A4B-it"}'
# -> {"ok":true,"status_code":200,"latency_ms":412,...} (the key is never returned)
# list, then delete
curl https://inference.raindragon.ai/api/v1/management/fallbacks -H "Authorization: Bearer $RD_MGMT_KEY"
curl -X DELETE https://inference.raindragon.ai/api/v1/management/fallbacks/google/gemma-4-26B-A4B-it \
-H "Authorization: Bearer $RD_MGMT_KEY"A PUT replaces the fallback, so an omitted fallback_model is cleared. Omit fallback_api_key on an update to keep the saved key. Turning off one model's fallback ( "is_active": false) does not hand that model to the catch-all.
Errors
- 401: missing, unknown, revoked or expired management key.
- 403: an inference key was used, or the key lacks the scope.
- 404: no fallback for that model. 422: invalid input, e.g. a non-https URL or a model we do not serve. 429: rate limited; see
Retry-After.
For Claude Code, Codex and other agents
- Give the agent a management key, not an inference key, in an environment variable such as
RD_MGMT_KEY. Grant onlyfallbacks:readif it only needs to inspect. - Prefer
PUTand/bulk: they are idempotent, so an agent can re-run them safely and readcreated/updated/unchangedto see what changed. - Call
/fallbacks/testafter a change, and never print the provider key. Responses never contain it. - Revoke the key in Settings when the job is done, or give it a short expiry.
