The simplified, key-first surface for Routing Studio. The customer never sees a “preference” object — the server find-or-creates a hidden per-key preference under the hood and ensures the binding row points at it.
Reach for this endpoint when you’re tuning a single API key. Reach for /api/v1/routing-preferences when you want a shared rule set that spans many keys or acts as a team default.
Authentication
Requires a Bearer token with the billing API key scope and access to the key (caller owns it, or has access through the active org).
GET
Read the per-key rules and the resolved binding state.
curl https://www.hitheo.ai/api/v1/keys/{id}/routing-rules \
-H "Authorization: Bearer $THEO_API_KEY"
const snap = await theo.routingRules.get(keyId);
console.log(snap.active); // true if these rules drive completions today
console.log(snap.shared_binding); // populated when the key is bound to a shared preference
Response
{
"key_id": "key_abc",
"rules": [
{
"id": "r_a4b8c01x9y",
"pattern": "\\b(clause|provision|indemnity|warranty)\\b",
"target_mode": "think",
"confidence": 0.92,
"description": "Contract terms get the analytical engine."
}
],
"examples": [
{ "prompt": "Look at this clause", "expected_mode": "think" }
],
"confidence_floor_overrides": { "think": 0.65 },
"active": true,
"shared_binding": null
}
active: true — these rules drive completions on this key right now.
active: false — the key inherits a default (or is bound to a shared preference); rules are still editable but inactive until saved or until the shared binding is cleared.
shared_binding — populated when the key is bound to a shared preference instead of its hidden row. Render the shared rules read-only and offer an “Override on this key” button.
PUT
Replace the per-key rules / examples / overrides. The route find-or-creates the hidden preference and ensures the binding points at it.
Up to 50 rules. Same shape as routing-preferences.
Up to 30 few-shot examples.
confidence_floor_overrides
Per-mode confidence-floor overrides.
curl -X PUT https://www.hitheo.ai/api/v1/keys/{id}/routing-rules \
-H "Authorization: Bearer $THEO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{
"pattern": "\\b(clause|provision|indemnity|warranty)\\b",
"target_mode": "think",
"confidence": 0.92,
"description": "Contract terms get the analytical engine."
}
],
"examples": [{ "prompt": "Look at this clause", "expected_mode": "think" }]
}'
await theo.routingRules.set(keyId, {
rules: [
{
pattern: "\\b(clause|provision|indemnity|warranty)\\b",
target_mode: "think",
confidence: 0.92,
description: "Contract terms get the analytical engine.",
},
],
examples: [{ prompt: "Look at this clause", expected_mode: "think" }],
});
DELETE
Clear the per-key rules: drops the binding so the resolution cascade falls back to org default → user default → none, and deletes the hidden preference row. Existing bindings to a non-hidden (shared) preference are left alone.
curl -X DELETE https://www.hitheo.ai/api/v1/keys/{id}/routing-rules \
-H "Authorization: Bearer $THEO_API_KEY"
Errors
400 routing_preference_invalid — Validation failure (vendor name, uncompilable regex, etc.).
404 not_found — Key doesn’t exist, is revoked, or isn’t accessible to the caller.