Core resources

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

id
string
UUID. Stable across the proxy lifetime; used in host routing and permission tags.
name
string
Human-readable label. Free-form.
provider
enum
One of openai, anthropic, google, mistral.
upstreamUrl
string (read-only)
Derived from provider server-side. Returned for visibility but not user-settable.
allowedModels
string[]
Allow-list of model identifiers. Empty array = all provider models allowed.
defaultModel
string?
Model used when the caller does not specify one.
logConversations
boolean
If true, full prompt + completion are AES-256-GCM encrypted to Redis with a 7-day TTL.
auth
object
Inbound auth: { "mode": "aifw_api_key" } or { "mode": "jwt", "jwksJson": "..." }.
budget
object?
Optional spend cap. { "period": "monthly", "capUsd": 200, "hardBlock": false }. Period is one of fixed, daily, weekly, monthly.
proxyHost
string (read-only)
The host your application sends LLM traffic to. Returned after proxy wiring completes.
createdAt
number
Unix timestamp (seconds).
What we never return

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#

GET/api/llm

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#

POST/api/llm

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

name*
string
Human-readable label.
provider*
enum
One of openai, anthropic, google, mistral.
providerKey
string
Plaintext provider API key. Encrypted before persistence; never returned again.
allowedModels
string[]
Allow-list of model identifiers. Empty / omitted = all models allowed.
defaultModel
string
Used when the caller does not pass one.
logConversations
boolean
Enable encrypted conversation logging (7-day TTL). Default false.
auth
object
Inbound auth config. Defaults to { "mode": "aifw_api_key" }.
budget
object
Spend cap. See Budgets.
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#

GET/api/llm/:id

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#

PATCH/api/llm/:id

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#

DELETE/api/llm/:id

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#

POST/api/llm/:id/re-resolve

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#

GET/api/llm/:id/rules
curl https://app.aironclaw.com/api/llm/$ID/rules \
  -H "Authorization: Bearer $AIFW_PAT"

Replace rules#

PUT/api/llm/:id/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#

POST/api/llm/:id/budget/reset

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#

GET/api/llm/:id/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)#

PUT/api/llm/:id/keys/:credId/budget

Read or upsert the budget for a specific (proxy, key) pair. The same path supports GET (read), PUT (upsert) and DELETE (remove).

PUT body

period*
enum
One of fixed, daily, weekly, monthly.
capUsd*
number
Cap in US dollars. Non-negative.
hardBlock
boolean
If true, the firewall returns 402/429 once the cap is reached. Default false.
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#

POST/api/llm/:id/keys/:credId/budget/reset

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)#

GET/api/llm/:id/usage

Query

months
number
Trailing months to return (1–36, default 12).
curl "https://app.aironclaw.com/api/llm/$ID/usage?months=6" \
  -H "Authorization: Bearer $AIFW_PAT"

Daily history + budget window#

GET/api/llm/:id/usage/daily

Query

days
number
Trailing days to return (1–30, default 14).

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#

GET/api/llm/:id/keys/:credId/usage/daily
Scope of the per-key daily series

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#

DELETE/api/llm/:id/usage/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)

all
boolean
If true, removes every daily hash in the 30-day window.
before
YYYYMMDD
Removes entries on or before this day (inclusive).

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)#

GET/api/llm/:id/logs

Query

from
epoch seconds
Lower bound (inclusive).
to
epoch seconds
Upper bound (inclusive).
limit
number
1–200 (default 50). Newest first.
curl "https://app.aironclaw.com/api/llm/$ID/logs?limit=50" \
  -H "Authorization: Bearer $AIFW_PAT"

Log detail (decrypts plaintext)#

GET/api/llm/:id/logs/:logId

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#

DELETE/api/llm/:id/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"