Skip to content
Effloow
← Back to article
EFFLOOW LAB LAB-RUN

Openrouter Guardrails Gateway Spend Governance Poc 2026

Evidence notes document the bounded local or source-based checks behind an Effloow article. They are not product endorsements, legal advice, or benchmark claims.
  • Slug: openrouter-guardrails-gateway-spend-governance-poc-2026
  • Run date: 2026-07-27
  • Track: api-backed-poc
  • Evidence level: api-backed-lab (partial — see Limitations)
  • Machine artifact: data/lab-runs/openrouter-guardrails-gateway-spend-governance-poc-2026.openrouter.json
  • Runner: ad-hoc python3 + urllib script (no SDK, no third-party deps)
  • Credentials: one existing Effloow workspace inference key (sk-or-v1…). No management key, no provisioning key. Key material scrubbed from every recorded body.
  • Spend: under one cent total for the whole run.

Why this run exists

OpenRouter's Guardrails docs and OpenRouter's own launch post disagree about which HTTP status a blocked request gets back. The docs guide says 403. The 2026-05-29 announcement says 402 for a budget block, 404 for a disallowed model or provider, 403 for prompt-injection and DLP blocks. That difference is not cosmetic: retry logic, alerting, and billing dashboards all branch on the status code. So the question for this run was narrow and testable — what does the live API actually return, and does a blocked request cost money?

Environment

Item Value
Base URL https://openrouter.ai/api/v1
Auth workspace inference key
Model under test openai/gpt-4o-mini
Client python3 stdlib urllib.request
Headers sent Authorization, Content-Type, HTTP-Referer, X-Title
Date 2026-07-27

Commands

Three scripts were run. Full source is reproducible from the recorded request bodies in the JSON artifact; the shape was:

req = urllib.request.Request(
    "https://openrouter.ai/api/v1/chat/completions",
    method="POST",
    data=json.dumps(body).encode(),
    headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json",
             "HTTP-Referer": "https://www.effloow.com", "X-Title": "Effloow Lab"},
)

Run 1 — read-only key and guardrail-management probes:

GET /key
GET /guardrails

Run 2 — five chat-completion variants, max_tokens: 8, prompt "Reply with exactly the word: OK":

control            model=openai/gpt-4o-mini
bad model          model=acme/definitely-not-a-real-model
allowlist block    provider={"only":["Groq"],"allow_fallbacks":false}
price ceiling      provider={"max_price":{"prompt":1e-7,"completion":1e-7},"allow_fallbacks":false}
zdr routing        provider={"zdr":true,"allow_fallbacks":false}

Run 3 — billing check, executed twice:

GET /key                    (read usage)
5x POST /chat/completions   (allowlist-block variant)
sleep 4
GET /key                    (read usage)

Results

Status-code matrix (measured)

Check Status Body / notable fields
GET /key 200 limit: null, limit_reset: null, limit_remaining: null, include_byok_in_limit: false, is_management_key: false, is_provisioning_key: false
GET /guardrails with inference key 401 {"error":{"message":"Invalid management key","code":401}}
Control completion 200 provider: "Azure", usage.total_tokens: 16, usage.cost: 0.0000033
Invalid model ID 400 "acme/definitely-not-a-real-model is not a valid model ID"
Provider allowlist violation 404 "No allowed providers are available for the selected model." + metadata.available_providers: ["azure","openai"], metadata.requested_providers: ["groq"]
Price ceiling too low 404 "No endpoints found that satisfy the max price for this request"
ZDR-only routing 200 succeeded, provider: "Azure", cost 0.0000033

Billing check

Cycle Blocked requests Statuses Usage delta (USD)
1 5 404 ×5 0.0000066
2 5 404 ×5 0.0000000

Cycle 1's delta is exactly 2 × 0.0000033 — the two successful control calls from run 2 settling late. Cycle 2 ran with no successful calls in between and moved account usage by exactly $0.00 across five blocked requests. Conclusion: requests rejected at the routing/restriction layer were not billed.

Absolute account balance is deliberately omitted from the artifact; only deltas were recorded.

What worked

  • Read-only key introspection is a genuine zero-cost pre-flight check. GET /key exposes limit, limit_remaining, limit_reset, and include_byok_in_limit, so a deploy gate can assert "this key has a cap" before shipping an agent.
  • Restriction violations return machine-readable metadata naming both the requested and the available providers. That is enough to write a useful operator error message without guessing.
  • Rejections are free. Ten blocked calls, zero cents.

What failed / was not reachable

  • No budget cap was created. The available key is an inference key; GET /guardrails returned 401 Invalid management key. So the actual USD-cap rejection path was never exercised. Whether a tripped budget returns 402 or 403 is docs-stated only, not measured here.
  • Prompt-injection and PII/DLP guardrails were not exercised at all. Detection accuracy, recall, and false-positive behavior are [DATA NOT AVAILABLE] as Effloow evidence.
  • The 404s measured here come from per-request provider-routing constraints, which exercise the same allow/deny decision path as an allowlist guardrail but are not the Guardrails feature itself. This is an important caveat and is stated as such in the article.

Limitations

  1. Single workspace, single model (openai/gpt-4o-mini), single day. Status codes may differ by model, provider set, account tier, or after a vendor change.
  2. max_tokens was 8 on every call; no long-context or streaming path was tested.
  3. The sleep 4 before the second usage read is a heuristic for settlement lag, not a documented guarantee. Cycle 1 shows settlement can lag at least one request round.
  4. No load, no concurrency, no sustained soak. This says nothing about behavior under burst.
  5. Vendor pricing and guardrail feature descriptions are quoted from OpenRouter's own docs and announcement; they were not independently priced or benchmarked.

Sources consulted

  • OpenRouter Guardrails guide — https://openrouter.ai/docs/guides/features/guardrails (re-read live on 2026-07-27; the guide states verbatim: "Note that budget limits and allowlist restrictions also produce 403 responses, but only runtime content checks include openrouter_metadata stage details." Our measured restriction responses were 404, matching the announcement's number rather than the guide's. Note the caveat in "What failed": our 404s came from per-request routing constraints, not from a configured Guardrails allowlist, so this is a documented mismatch on the routing layer and not a formal disproof of the guide's sentence.)
  • OpenRouter Guardrails announcement (2026-05-29) — https://openrouter.ai/blog/announcements/guardrails/
  • OpenRouter Guardrails API reference (create/update/list guardrail) — https://openrouter.ai/docs/api/api-reference/guardrails/create-guardrail
  • Live OpenRouter API responses recorded in this run (primary evidence)

Read the article

This note supports the public article and records what was actually checked.

Open article →