Crux
GuidesRouting & Fallback

Routing Receipts

Inspect the concrete model and every routing decision for a call.

Which model actually ran, and what did it cost? When a call goes through a router, a fallback chain, and a retry wrapper, the answer is not obvious from the result text. Read result.routing:

const result = await generate(prompt, {
  model: productionModel,
  input,
  routing,
});

console.log(result.routing?.model);
console.log(result.routing?.trace);

A routed call produces one append-only RoutingReceipt:

interface RoutingReceipt {
  model: string;
  cost: number | undefined;
  firstTokenAt?: number;
  trace: RoutingStep[];
}

model is always the final concrete provider model id. trace is ordered from outermost decision to nested decision. firstTokenAt is present for streams and records elapsed milliseconds from routed stream hand-off to the first emitted token.

Receipts are exposed on:

  • result.routing for generate()
  • (await streamResult.completion).routing for stream()
  • FallbackExhaustedError.routing
  • CascadeExhaustedError.routing
  • stream completion errors after mid-stream failure

The same receipt is what devtools renders: each routed resolution attaches it as a routing.report observability artifact. The routing.report artifact carries that kind tag; the receipt itself has no kind property, so read its fields directly. See the Observability reference for the artifact shape and how devtools presents TTFT, attempt errors, and cascade notes from it.

On this page

No Headings