Build Route Evidence Capsules for AI API Gateways

python dev.to

Build Route Evidence Capsules for AI API Gateways

A model route can look stable from the client side while the evidence around it is already drifting.

The HTTP call still works. The OpenAI-compatible request shape still works. The model alias still resolves. The application team sees no broken test. Meanwhile, the dated price row may have changed, a cache field may no longer match the forecast, a policy exception may have moved from temporary to permanent, or the buyer may be looking at a stale spreadsheet that does not name the source date.

That gap is where Tier 1 and Tier 2 teams lose time. Engineering can explain the request. Finance can explain the budget. Security can explain which inputs were redacted. Procurement can explain why a route was approved. But those explanations often live in different places.

A route evidence capsule puts them in one small artifact.

The capsule is not a dashboard. It is not a public usage claim. It is not a private log export. It is a compact review object that travels with a route change, workbook, SDK example, incident review, or deployment gate.

It answers one question:

If this AI API route ships today, can a reviewer see exactly which model row, policy checks, pricing source, and redacted receipt shape supported the decision?

I will use AIWave as the concrete example because it exposes both a live route table and a dated public pricing snapshot. The same pattern applies to any OpenAI-compatible gateway that gives engineers one client surface while still requiring accountable route choices behind the scenes.

What belongs in the capsule

A useful capsule is intentionally small. It should be easy to attach to a pull request, release note, procurement packet, support escalation, or internal runbook.

At minimum, include these fields:

Field Purpose
capsule_id Stable identifier for the route decision
checked_at When the evidence was collected
route_name The exact model or gateway route used by the client
client_shape The API family expected by the application
pricing_sources Live and dated sources that were checked
price_row The public base row used for planning
group_note Reminder that account or key group can alter final billing
policy_checks Data, region, retry, timeout, and tool-use boundaries
receipt_shape Redacted fields expected after a request completes
unknowns Items that must not be inferred
verdict pass, review, or block

The most important field is often unknowns. Teams get into trouble when they let a missing denominator, missing cache field, or missing route receipt turn into a confident statement. The capsule should make that uncomfortable. If the evidence is absent, say so.

Source check from September 17, 2026

During this run on September 17, 2026, I checked AIWave's public pricing sources before writing the article.

The live route table at https://aiwave.live/api/pricing returned HTTP 200, success=true, 68 route rows, auto_groups=["default"], and pricing version a42d372ccf0b5dd13ecf71203521f9d2.

The dated public snapshot at https://aiwave.live/api/v1/pricing returned HTTP 200, checked=2026-09-10, updated_at=2026-09-10, currency USD, unit per_1m_text_tokens, source /api/pricing, source page https://aiwave.live/pricing, pricing version 8c7a0c0b30661ccbc13d142cb54d1e4ae445fe774b2c6fa501080db97c7a3e56, and 64 public model rows.

Those two sources should not be collapsed into one vague statement like "current pricing". The live route table is the operational source. The dated snapshot is the public evidence artifact. A capsule can use both, but it should record which one provided which fact.

Example rows from the dated public snapshot:

Model ID Provider family Input / 1M text tokens Cache-hit input / 1M Output / 1M text tokens Effective date
deepseek-v4-flash DeepSeek $0.638 $0.0202884 $1.914 2026-08-27
deepseek-v4-pro DeepSeek $1.914 $0.0637362 $5.742 2026-08-27
glm-4.5 GLM $0.6975 $0.1800003375 $2.1699999225 2026-08-27
minimax-m2.5 MiniMax $0.46866 $0.046866 $1.87464 2026-08-27
kimi-k2.7-code Kimi $1.89 $0.28500066 $5.99999967 2026-08-27
qwen3.8-27b Qwen $0.6695133382 not listed $2.6780533528 2026-08-27

These rows are public base rates, not final invoices. Final cost still depends on the account or key group, selected route, cache behavior, retry count, output length, and the private request receipt.

That is exactly why the capsule should carry both planning evidence and receipt expectations.

A capsule schema

Start with a schema that is boring on purpose.

{"capsule_id":"route_capsule_deepseek_v4_flash_2026_09_17","checked_at":"2026-09-17T13:05:00Z","route_name":"deepseek-v4-flash","client_shape":"openai.chat.completions","pricing_sources":{"live_route_table":"https://aiwave.live/api/pricing","dated_snapshot":"https://aiwave.live/api/v1/pricing"},"price_row":{"currency":"USD","unit":"per_1m_text_tokens","input":0.638,"cache_hit_input":0.0202884,"output":1.914,"effective_date":"2026-08-27"},"group_note":"Public row is a base rate. The final request receipt controls applied billing.","policy_checks":{"prompt_logged":false,"api_key_logged":false,"retry_cap":1,"timeout_ms":60000,"tool_budget_required":true},"receipt_shape":{"request_id":"present","model":"present","input_tokens":"numeric","output_tokens":"numeric","cache_hit_tokens":"numeric_or_null","charged_amount":"private_receipt_only"},"unknowns":["Future route changes after checked_at","Final output length before request completion","Private account group unless authenticated receipt is inspected"],"verdict":"review"}
Enter fullscreen mode Exit fullscreen mode

Notice that charged_amount is not copied into a public artifact. The capsule records the expected receipt shape, not customer-specific billing data. That distinction keeps the artifact useful without dragging private operations into places they do not belong.

Build it in Python

Here is a small capsule builder. It fetches the dated public snapshot, selects a route, and writes a review object. It uses an environment variable for the API key pattern in the example, but this specific public pricing call does not require a secret.

import datetime as dt
import json
import os
import urllib.request

SNAPSHOT_URL = "https://aiwave.live/api/v1/pricing"
LIVE_URL = "https://aiwave.live/api/pricing"


def fetch_json(url: str) -> dict:
    request = urllib.request.Request(
        url,
        headers={"User-Agent": "route-evidence-capsule/1.0"},
    )
    with urllib.request.urlopen(request, timeout=20) as response:
        return json.loads(response.read().decode("utf-8"))


def find_model(snapshot: dict, model_id: str) -> dict:
    for row in snapshot.get("models", []):
        if row.get("id") == model_id:
            return row
    raise ValueError(f"model row not found: {model_id}")


def build_capsule(model_id: str) -> dict:
    snapshot = fetch_json(SNAPSHOT_URL)
    row = find_model(snapshot, model_id)

    missing = []
    if row.get("cache_hit_usd_per_1m_tokens") is None:
        missing.append("cache_hit_input is not listed for this public row")

    verdict = "pass" if not missing else "review"

    return {
        "capsule_id": f"route_capsule_{model_id}_{dt.date.today().isoformat()}",
        "checked_at": dt.datetime.now(dt.UTC).isoformat(),
        "route_name": model_id,
        "client_shape": "openai.chat.completions",
        "pricing_sources": {
            "live_route_table": LIVE_URL,
            "dated_snapshot": SNAPSHOT_URL,
            "snapshot_checked": snapshot.get("checked"),
            "snapshot_version": snapshot.get("pricing_version"),
        },
        "price_row": {
            "provider": row.get("provider"),
            "currency": snapshot.get("currency"),
            "unit": snapshot.get("unit"),
            "input": row.get("input_usd_per_1m_tokens"),
            "cache_hit_input": row.get("cache_hit_usd_per_1m_tokens"),
            "output": row.get("output_usd_per_1m_tokens"),
            "effective_date": row.get("effective_date"),
        },
        "policy_checks": {
            "api_key_source": "os.environ.get('AIWAVE_API_KEY')",
            "api_key_logged": False,
            "prompt_logged": False,
            "timeout_ms": 60000,
            "retry_cap": 1,
        },
        "unknowns": missing,
        "verdict": verdict,
    }


if __name__ == "__main__":
    # Pattern only. Do not print or persist the actual key.
    api_key = os.environ.get("AIWAVE_API_KEY")
    capsule = build_capsule("deepseek-v4-flash")
    print(json.dumps(capsule, indent=2))
Enter fullscreen mode Exit fullscreen mode

In production, I would add a second fetch against the live route table and compare route availability, endpoint support, and pricing version. I would also reject a capsule if the model row exists in only one source unless the release owner explicitly accepts that mismatch.

Review gates

The capsule becomes useful when it blocks vague approvals.

Add these gates before a route ships:

Gate Pass condition Review condition Block condition
Source freshness Pricing source checked in the current run Dated snapshot is older than planned Source cannot be fetched
Row identity Exact model ID exists Alias maps through an undocumented route Only a similar model is found
Unit clarity Currency and unit are present Unit exists but examples mix units Unit is missing
Cache semantics Cache row is present or explicitly absent Cache field differs across sources Forecast assumes cache when no row exists
Receipt safety Receipt shape is redacted A reviewer asks for private fields Secret, prompt, or customer data appears
Billing group Group note is explicit Group is known only after auth Public text claims final billing without receipt
Retry behavior Retry cap is named Retry policy differs by route Forecast ignores retries

This is a better workflow than a long meeting where everyone says "pricing looks current" without naming the source.

The gate should produce one of three verdicts:

pass   - evidence supports the route decision
review - route can proceed only with named unknowns accepted
block  - source, row, unit, policy, or receipt safety failed
Enter fullscreen mode Exit fullscreen mode

For many model changes, review is the honest result. A missing cache row is not always a deployment blocker. A changed version field is not always a bug. But both should be visible before the route becomes a default in code, a spreadsheet, or a public example.

Where to store capsules

Do not bury route evidence in chat history. Store capsules near the thing they approve.

For an SDK, put them under evidence/routes/ and link them from the pull request. For a procurement workbook, attach the capsule JSON next to the workbook export. For a production route change, store the capsule with the release artifact. For an incident, create a post-incident capsule that records which assumptions were wrong.

Keep the artifact small enough that a reviewer reads it.

A practical naming scheme:

evidence/routes/
  2026-09-17-deepseek-v4-flash-chat-completions.json
  2026-09-17-glm-4-5-cache-policy.json
  2026-09-17-qwen3-8-27b-no-cache-row-review.json
Enter fullscreen mode Exit fullscreen mode

The name should include the date, model ID, and reason for review. That makes later searches useful without opening every file.

What not to put in the capsule

The capsule is an evidence boundary. Keep it clean.

Do not include API keys. Do not include prompts. Do not include raw responses. Do not include customer identifiers. Do not include private revenue, registration, or request volume. Do not use the capsule as marketing proof. Do not claim a route is faster, more reliable, or better unless the exact benchmark and date are in scope.

The capsule should help a serious reviewer say:

  1. Which route was chosen.
  2. Which pricing sources were checked.
  3. Which date and unit apply.
  4. Which policy constraints were accepted.
  5. Which unknowns remain.
  6. Which private facts are intentionally excluded.

That last point matters. A good artifact is not only clear about what it knows. It is clear about what it refuses to expose.

A release checklist

Before a route evidence capsule is accepted, run this checklist:

[ ] Exact route name appears in the live route table or approved source
[ ] Public snapshot row is present, dated, and uses USD per 1M text tokens
[ ] Cache-hit field is either recorded or explicitly absent
[ ] Account or key group note is present
[ ] Retry cap and timeout are named
[ ] Receipt shape is redacted
[ ] No API key, prompt body, raw customer data, or private usage number appears
[ ] Verdict is pass, review, or block
[ ] Reviewer can reproduce the public source checks
Enter fullscreen mode Exit fullscreen mode

This checklist is deliberately plain. Fancy controls fail when people cannot run them during a real release. A capsule should be easy to regenerate and easy to challenge.

Why this helps Tier 1 and Tier 2 teams

Tier 1 and Tier 2 buyers rarely reject AI API work because an engineer cannot write a request. They slow down because every serious route change crosses multiple concerns: cost, source date, region, retention posture, retry behavior, support path, and receipt auditability.

Route evidence capsules reduce translation work between those concerns.

Engineering gets a stable artifact for code review. Finance gets dated units and source URLs. Security gets a redaction boundary. Procurement gets a small trail that explains why one route was accepted without relying on vague claims. Support gets a way to inspect drift without asking for secrets.

The real benefit is cultural: a team stops treating model choice as a hidden preference and starts treating it as a reviewable decision.

When the next route changes, the question is no longer "Which model did we like?" It becomes "Which evidence capsule supports this route today?"

That is a much better question to ship with.

Source: dev.to

arrow_back Back to Tutorials