LowRouterBeta

Per-request metadata

Every successful response from the gateway carries a top-level lowrouter_metadata field:

JSON
{
  "id": "chatcmpl-...",
  "choices": [...],
  "usage": {...},
  "lowrouter_metadata": {
    "provider": "openai",
    "region": "eu-west",
    "energy_wh": 0.0021,
    "carbon_gco2e": 0.00057,
    "carbon_intensity_gco2_per_kwh": 270,
    "estimation_methodology": "ecologits-calculated",
    "routing_mode": "auto",
    "routing_reason": "lowest_carbon_intensity",
    "fallback_occurred": false,
    "providers_attempted": ["openai"]
  }
}

Two kinds of values appear in this block, and they don’t carry the same weight:

  • Recorded — facts about the routing decision LowRouter itself made: provider, region, routing_mode, routing_reason, fallback_occurred, providers_attempted, requested_alias. The region is the one whose endpoint we called; what that guarantees about data residency beyond the routing itself is defined by the upstream provider’s own terms.
  • Estimated — modeled numbers: energy_wh, carbon_gco2e, carbon_intensity_gco2_per_kwh. Produced per the methodology from annual grid averages, and absent rather than fabricated when we can’t classify the request.

Field reference

provider

The upstream that actually served the request. Matches an id in GET /providers (a discovery endpoint) and the provider segment of a model ID.

region

The region the upstream served from. Strings like eu-west, us-east, us-west. The region is the one encoded in the resolved model ID’s locode.

energy_wh

Total energy estimated for the request, in watt-hours. Computed from the resolved model’s per-token energy coefficients and the request’s token counts. See methodology.

carbon_gco2e

Total CO₂e estimated for the request, in grams. Derived from energy_wh, the data-center overhead (PUE 1.20), and the grid intensity for the serving region.

carbon_intensity_gco2_per_kwh

The grid carbon intensity used for the serving region, in grams of CO₂e per kWh.

estimation_methodology

Identifies how the estimate was produced (e.g. an EcoLogits-based calculation). Present when an estimate was made.

routing_mode

auto when the router chose the route for you (an auto/<creator>/<model> request), explicit when you named the provider and region yourself.

routing_reason

Why the router landed where it did. For an auto-routed request this is one of eu_sovereign_preferred, lowest_carbon_intensity, lowest_cost, round_robin, or only_route. See routing.

fallback_occurred

true if the route changed after selection. LowRouter does not silently substitute providers — an explicit ID is a pin and an auto-routed request commits to the winner of its ranking — so this reads false on current traffic. It stays on the response, and in your usage export, because historical rows can carry true.

providers_attempted

The list of providers tried for this request, in order.

requested_alias

Present only when the request addressed a model alias ("model": "alias/big"). Carries the alias as sent (alias/big), while the response’s top-level model field carries the full model ID the alias resolved to. Absent on non-aliased requests.

Worked scenario: “why did this request go to us-east?”

Your dashboard shows one row served from us-east in a week of otherwise-EU traffic. The metadata of that response answers it without guesswork:

JSON
"lowrouter_metadata": {
  "provider": "openai",
  "region": "us-east",
  "routing_mode": "auto",
  "requested_auto": "auto/openai/gpt-4.1",
  "routing_reason": "lowest_carbon_intensity",
  "eu_sovereign": false,
  "providers_attempted": ["openai"]
}

Read it as a trace: you sent auto/openai/gpt-4.1, so the route was LowRouter’s to choose, and eu_sovereign: false says plainly that no sovereign route existed for that model — auto-routing prefers EU-sovereign providers in EU/EEA regions, but falls through rather than failing when a model has none. routing_reason then names what decided among what was left. Nothing was misrouted, and nothing was silently substituted: providers_attempted lists one provider.

If a US route is unacceptable for that workload, this is the signal to move it from auto/ to a pinned model ID or an alias: an explicit route fails loudly instead of falling back outside your constraint. See routing for the pinning syntax.

Headers

The gateway sets an X-Request-ID header on every response. Use it to correlate a request with your own logs or when reporting an issue.

Streaming

For streamed requests, lowrouter_metadata arrives on the final chunk (the one before [DONE]), carrying the same fields as the non-streaming block. Earlier chunks don’t include it. See first completion → streaming.

When metadata is partial

The eco fields (energy_wh, carbon_gco2e, carbon_intensity_gco2_per_kwh) can be absent when:

  • The resolved model’s parameter count is unknown and we’d rather omit the number than fabricate one.
  • The request consumed no tokens (e.g. a non-completion response).
  • The upstream returned an error mid-stream that prevented usage accounting.

When they’re missing, the dashboard shows the row with a for the carbon column and a note linking to the methodology page. The routing fields (provider, region, routing_mode, …) are still present.

Privacy

The lowrouter_metadata block contains nothing about prompt or response content — only the resolved route and the metric estimates. It is safe to log on the client side; we do.