Skip to main content

Explain a Route

Dry-run a routing decision through the live resolver: get the ordered candidate chain an operation would use, or a fail-closed explanation, without spending a model call.

POST /v1/ai/routes:explain answers "what would this operation route to right now" without spending a model call. The question runs through the same resolver that serves live traffic, so the answer is evidence rather than a forecast: the ordered candidate chain that would serve the operation, and every candidate the policy discarded, each with the constraint that discarded it. For a compliance review, the rejected list is often the more valuable half, because it shows the policy actively removing what it is supposed to remove.

The request names an operation_type and may pin a model or a class. Unpinned, the resolver uses the operation's effective class and walks its chain. Pinning a model asks "could we be routed to this model for this operation", which is the direct way to verify a denial: a denied model appears under rejected with reason model_denied no matter what else would have permitted it. fallback_scope in the response reports how far fallback may reach for this plan, for example class_chain when the class's whole chain is in play.

When the policy permits no route, the response is still a success (the endpoint returns 201 on every answered question) with routable: false, a reason code, and a plain-language message. This is deliberate: a policy that permits no route is a valid configuration whose consequence is that the live call fails closed. The dry run reports that consequence honestly instead of dressing it up as a client error.

POST/v1/ai/routes:explain

Body fields

operation_type*stringThe operation to route, for example extraction or classification.
modelstringOptional. Pin a specific logical model instead of letting the operation's class choose.
classstringOptional. Pin a specific model class instead of the operation's mapped one.

cURL: Explain the extraction route

curl -X POST "https://api.talonic.com/v1/ai/routes:explain" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"operation_type": "extraction", "model": "claude-sonnet", "class": "standard"}'

Response: 201 Routable plan

{
  "operation_type": "extraction",
  "routable": true,
  "class": "standard",
  "fallback_scope": "class_chain",
  "candidates": [
    { "model": "claude-sonnet", "provider": "bedrock", "region": "eu", "custom_endpoint": false }
  ],
  "rejected": [
    { "model": "gpt-balanced", "provider": "openai", "region": "global", "reason": "provider_not_allowed" }
  ]
}

Response: 201 Fail-closed explanation

{
  "operation_type": "document_ocr",
  "routable": false,
  "reason": "no_compliant_route",
  "message": "No route satisfies this workspace policy for this operation, so the call fails closed rather than reaching a provider the policy does not permit.",
  "candidates": [],
  "rejected": [
    { "model": "mistral-ocr", "provider": "mistral", "region": "global", "reason": "provider_not_allowed" }
  ]
}
The explainer evaluates the policy that is live right now, which for routing purposes is the active one. Use it immediately after activating a change to confirm the change did what was intended, and periodically as standing evidence: the response is produced by the production resolver, so it cannot drift from what production does.

candidates is ordered: the first entry is what a live call would try first, and later entries are the fallback order under the reported fallback_scope. Every candidate carries only model, provider, region, and custom_endpoint; wire-level model identifiers, endpoint hosts, and credentials never appear. That projection is the same one every route on this surface applies, so nothing about the platform's infrastructure crosses the API boundary through a dry run either.

Frequently asked questions

Does routes:explain cost a model call or credits?+
No. It is a dry run through the routing resolver only; no provider is contacted and no model call is made. It is safe to call as often as verification requires, subject to normal API rate limits.
Why does an unroutable operation return 201 instead of an error?+
Because the question was answered. A policy that permits no route is a valid configuration, and its consequence, the call failing closed, is reported as routable: false with a reason and a plain-language message. A 4xx is reserved for malformed requests, not for policies whose honest answer is "nothing routes".
Is the answer guaranteed to match live routing?+
The plan is computed by the same resolver that serves live traffic, against the same live policy and catalog, so it is evidence of what would happen at that moment. A subsequent policy change, catalog change, or platform floor change changes the answer; re-run the explainer after any of those to refresh the evidence.