LLM Proxies
An LLM Proxy is a managed gateway in front of a single LLM provider (OpenAI, Anthropic, Google or Mistral). Provision them via this API and your app traffic flows through AIronClaw with rules, budgets, logs and audit applied centrally.
The LLM Proxy object#
A proxy ties together a provider, an inbound auth method, an (optional) provider API key, an allow-list of models, an optional budget and per-key permissions. The backing record is stored in Redis and the routing/policy enforcement happens in the gateway + the aifw Lua plugin.
Fields
openai, anthropic, google, mistral.provider server-side. Returned for visibility but not user-settable.{ "mode": "aifw_api_key" } or { "mode": "jwt", "jwksJson": "..." }.{ "period": "monthly", "capUsd": 200, "hardBlock": false }. Period is one of fixed, daily, weekly, monthly.providerKey ciphertext, internal IDs, and any other server-side machinery are stripped from every response by the same toSafeLlmProxy filter. You can never read a provider key back through the API after writing it.
Manage proxies#
List proxies#
Returns every LLM proxy owned by the caller, in creation order.
curl https://app.aironclaw.com/api/llm \
-H "Authorization: Bearer $AIFW_PAT"Create a proxy#
Creates the Redis record and immediately wires the matching gateway Service + Routes + aifw plugin. The proxy goes live on its proxyHost the moment the gateway returns. Until you attach an inbound credential (API key or JWT), every request gets a 401.
Body
openai, anthropic, google, mistral.{ "mode": "aifw_api_key" }.curl -X POST https://app.aironclaw.com/api/llm \
-H "Authorization: Bearer $AIFW_PAT" \
-H "Content-Type: application/json" \
-d '{
"name": "production-openai",
"provider": "openai",
"providerKey": "sk-...",
"allowedModels": ["gpt-4o", "gpt-4o-mini"],
"defaultModel": "gpt-4o-mini",
"logConversations": true,
"budget": { "period": "monthly", "capUsd": 200, "hardBlock": false }
}'Retrieve a proxy#
Fetches a single proxy by its UUID. Includes the current upstream DNS pin (when the gateway has resolved one) so you can verify routing.
curl https://app.aironclaw.com/api/llm/$ID \
-H "Authorization: Bearer $AIFW_PAT"Update a proxy#
Partial update. Send only the fields you want to change. Setting providerKey to null or empty string removes the stored key. Changing provider swaps the upstream URL automatically and updates the gateway service.
curl -X PATCH https://app.aironclaw.com/api/llm/$ID \
-H "Authorization: Bearer $AIFW_PAT" \
-H "Content-Type: application/json" \
-d '{ "allowedModels": ["gpt-4o"], "logConversations": false }'Delete a proxy#
Tears down the gateway resources, removes the Redis record, and strips any llm:<id>:* permission tags from your API keys. Idempotent: returns 404 if the proxy does not exist.
curl -X DELETE https://app.aironclaw.com/api/llm/$ID \
-H "Authorization: Bearer $AIFW_PAT"Re-resolve upstream IP#
AIronClaw pins the upstream provider IP at first contact for SSRF protection. Call this endpoint after the provider rotates DNS, or whenever you see upstream unreachable errors, to refresh the pin.
curl -X POST https://app.aironclaw.com/api/llm/$ID/re-resolve \
-H "Authorization: Bearer $AIFW_PAT"Rules#
Rules attach inline policy to the proxy: rate limits, IP ACLs, prompt-replace (DLP), model routing, prompt guards and Lua lambdas (phase="access" only). The full ruleset is replaced atomically on every PUT; there is no per-rule add/remove endpoint.
List rules#
curl https://app.aironclaw.com/api/llm/$ID/rules \
-H "Authorization: Bearer $AIFW_PAT"Replace rules#
Replaces the full rule set in one shot. Allowed rule_type values on LLM proxies: ip_acl, rate_limit, prompt_replace, model_route, prompt_guard, lambda (with phase="access"). Every rule must include a tools array — use ["*"] to apply globally.
curl -X PUT https://app.aironclaw.com/api/llm/$ID/rules \
-H "Authorization: Bearer $AIFW_PAT" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{
"rule_type": "ip_acl",
"tools": ["*"],
"action": "allow",
"cidrs": ["10.0.0.0/8", "203.0.113.0/24"]
},
{
"rule_type": "model_route",
"tools": ["*"],
"pattern": "^gpt-3\\.5",
"target_model": "gpt-4o-mini"
}
]
}'Budgets#
Two budget layers exist per proxy: a proxy-level cap (set on the proxy object via budget) and a per-(key, proxy) cap for fine-grained per-tenant control. Both share the same period semantics: fixed (no rollover), daily, weekly or monthly. Set hardBlock: true to refuse requests once the cap is hit; otherwise the budget is informational and only flags an alert.
Reset proxy window#
Zeros the current-window spend counter for the proxy. Daily history and monthly totals are preserved — only the enforcement counter is cleared. Returns 204 No Content.
curl -X POST https://app.aironclaw.com/api/llm/$ID/budget/reset \
-H "Authorization: Bearer $AIFW_PAT"List proxy keys#
Lists the API keys that have been granted access to this proxy (their credential carries an llm:<id>:* tag), with their per-key budget and current-window spend. Keys are shown masked (aifw_p…_xyz4).
curl https://app.aironclaw.com/api/llm/$ID/keys \
-H "Authorization: Bearer $AIFW_PAT"Per-key budget (get / set / delete)#
Read or upsert the budget for a specific (proxy, key) pair. The same path supports GET (read), PUT (upsert) and DELETE (remove).
PUT body
fixed, daily, weekly, monthly.curl -X PUT https://app.aironclaw.com/api/llm/$ID/keys/$CRED_ID/budget \
-H "Authorization: Bearer $AIFW_PAT" \
-H "Content-Type: application/json" \
-d '{ "period": "monthly", "capUsd": 50, "hardBlock": true }'Reset key window#
Zeros the current-window spend counter for the (key, proxy) pair. Returns 204 No Content. Returns 400 if no budget is configured for that pair.
curl -X POST https://app.aironclaw.com/api/llm/$ID/keys/$CRED_ID/budget/reset \
-H "Authorization: Bearer $AIFW_PAT"Usage#
Three flavors of usage data are exposed: a monthly summary with per-key breakdown, a daily series with per-model split, and a per-key daily series. Costs are computed at request time using the AIronClaw pricing table (the response includes the pricingVersion so you can detect price-list changes).
Monthly summary + per-key (current month)#
Query
curl "https://app.aironclaw.com/api/llm/$ID/usage?months=6" \
-H "Authorization: Bearer $AIFW_PAT"Daily history + budget window#
Query
Returns daily totals with per-model breakdown plus a snapshot of the running budget window: spentCents, tag (e.g. 2026-04 for monthly), and therollsOverAt timestamp.
curl "https://app.aironclaw.com/api/llm/$ID/usage/daily?days=7" \
-H "Authorization: Bearer $AIFW_PAT"Per-key daily history + budget window#
Per-key daily counters are notscoped per proxy — a single key's daily hash covers every proxy it has touched, so the top-line numbers reflect the key's entire activity. The per-model split lets you tell which proxies' models contributed.
curl "https://app.aironclaw.com/api/llm/$ID/keys/$CRED_ID/usage/daily?days=14" \
-H "Authorization: Bearer $AIFW_PAT"Delete history#
Removes daily usage hashes. Exactly one of the two query parameters must be provided. Budget-window enforcement counters are not touched — call budget/reset separately for that.
Query (one of)
The same shape exists scoped to a single key: DELETE /api/llm/:id/keys/:credId/usage/history.
curl -X DELETE "https://app.aironclaw.com/api/llm/$ID/usage/history?before=20260301" \
-H "Authorization: Bearer $AIFW_PAT"Logs#
When logConversations is enabled on a proxy, every request and response is encrypted with AES-256-GCM and written to Redis with a 7-day TTL. The list endpoint returns metadata only; full plaintext is fetched on demand from the detail endpoint.
List logs (metadata only)#
Query
curl "https://app.aironclaw.com/api/llm/$ID/logs?limit=50" \
-H "Authorization: Bearer $AIFW_PAT"Log detail (decrypts plaintext)#
Decrypts the conversation log on the server with the AIronClaw master key and returns the plaintext request/response. The response is never cached (Cache-Control: no-store).
curl https://app.aironclaw.com/api/llm/$ID/logs/$LOG_ID \
-H "Authorization: Bearer $AIFW_PAT"Purge logs#
Removes every log blob, metadata hash and the index for this proxy. Returns the number of removed entries.
curl -X DELETE https://app.aironclaw.com/api/llm/$ID/logs \
-H "Authorization: Bearer $AIFW_PAT"