Skip to main content

Auto-Router Management API

Manage auto-router configurations programmatically. Create routers, add routing rules, test configurations, and work the review queue -- all through the API.

For an overview of how auto-routing works, see Auto-Router. If your integration was built against the old keyword-based rules, see Upgrading from v1 for the breaking changes.

Use a service account key

These endpoints are designed for programmatic access. We recommend using a service account key rather than a personal key -- service account keys belong to the team (not a user), so you can separate API management from keys that are tied to budgets.

You can only access routers you created (admins can access all routers).

Create a router​

curl -X POST https://api.haimaker.ai/auto-router/new \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"router_name": "my-router",
"default_model": "openai/gpt-4o",
"rules": [
{
"rule_order": 1,
"example_prompts": [
"Write a Python function to deduplicate a list",
"Debug this TypeScript error: Cannot read properties of undefined",
"Refactor this SQL query to use a CTE"
],
"target_model": "anthropic/claude-sonnet-4-6"
},
{
"rule_order": 2,
"example_prompts": [],
"required_capabilities": ["vision"],
"target_model": "openai/gpt-4o"
}
]
}'

Rules are optional at creation time -- you can add them later. The default_model handles requests when no rule matches. The server embeds each rule's example prompts and stores the resulting centroid; you never send or manage embeddings yourself.

Rule fields​

FieldTypeDescription
rule_orderintPriority (lower = higher priority; breaks similarity ties)
example_promptsstring[]Example prompts that define what this rule matches (max 50). Embedded server-side.
match_thresholdfloatMinimum similarity (0-1) for the rule to fire. Omit for the default, 0.8.
required_capabilitiesstring[]Only fire when the request needs these capabilities
initial_turn_onlyboolOnly match on the first message in a conversation
enabledboolDisabled rules are kept but never match (default true)
target_modelstringModel to route to when this rule matches

Rule responses also include a read-only source field: manual for rules you created, mined for rules the tuner learned from traffic, migrated for rules converted from v1 keywords.

warning

keywords and keyword_categories are no longer accepted -- sending either returns a 400. The GET /auto-router/keyword-categories endpoint has been removed. See Upgrading from v1.

Available capabilities​

vision, function_calling, response_schema, audio_input, pdf_input, web_search, reasoning

Get router info​

curl https://api.haimaker.ai/auto-router/{router_id}/info \
-H "Authorization: Bearer YOUR_API_KEY"

Returns the full configuration including rules, derived model pool, associated keys, and the capture_enabled / auto_apply_enabled settings.

Update a router​

Update the router name, default model, or learning settings.

curl -X POST https://api.haimaker.ai/auto-router/{router_id}/update \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"default_model": "anthropic/claude-sonnet-4-6",
"capture_enabled": true,
"auto_apply_enabled": false
}'
FieldDescription
capture_enabledStore normalized prompts for tuning and the Traffic tab (30-day retention). Set false to opt out -- the router stops learning.
auto_apply_enabledLet high-confidence tuner proposals apply automatically. Set false and every proposal goes to the review queue instead.

Delete a router​

curl -X DELETE https://api.haimaker.ai/auto-router/{router_id}/delete \
-H "Authorization: Bearer YOUR_API_KEY"

Deleting a router unlinks all associated API keys (they will return an error if model: "haimaker/auto" is used).

List routers​

curl https://api.haimaker.ai/auto-router/list \
-H "Authorization: Bearer YOUR_API_KEY"

Returns all routers you created. Admins see all routers.


Rule management​

Add a rule​

curl -X POST https://api.haimaker.ai/auto-router/{router_id}/rules \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rule_order": 1,
"example_prompts": [
"Write a terraform module for a GKE cluster",
"Why is my helm upgrade stuck in pending-install?"
],
"target_model": "anthropic/claude-sonnet-4-6"
}'

Existing rules at or above the specified rule_order are shifted down automatically.

Update a rule​

curl -X PUT https://api.haimaker.ai/auto-router/{router_id}/rules/{rule_id} \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rule_order": 1,
"example_prompts": [
"Write a terraform module for a GKE cluster",
"Why is my helm upgrade stuck in pending-install?",
"Fix this Dockerfile so the build cache works"
],
"match_threshold": 0.75,
"target_model": "anthropic/claude-sonnet-4-6"
}'

Editing example_prompts recomputes the rule's centroid server-side.

Delete a rule​

curl -X DELETE https://api.haimaker.ai/auto-router/{router_id}/rules/{rule_id} \
-H "Authorization: Bearer YOUR_API_KEY"

Reorder rules​

Bulk reorder rules without changing their content:

curl -X POST https://api.haimaker.ai/auto-router/{router_id}/rules/reorder \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{"rule_id": "rule-abc", "rule_order": 1},
{"rule_id": "rule-def", "rule_order": 2},
{"rule_id": "rule-ghi", "rule_order": 3}
]
}'

Revert a mined rule​

One-click revert for rules the tuner created. The rule is disabled (not deleted) and the changelog records who reverted it.

curl -X POST https://api.haimaker.ai/auto-router/{router_id}/rules/{rule_id}/revert \
-H "Authorization: Bearer YOUR_API_KEY"

Only works on mined or migrated rules -- for rules you created manually, use delete instead.


Simulate routing​

Test which model would be selected for a given prompt without making an actual LLM request. Free and fast. The response is a full similarity breakdown, so this doubles as a debugger for thresholds and rule overlap.

curl -X POST https://api.haimaker.ai/auto-router/{router_id}/simulate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Write a Python script to parse CSV files"
}'

You can also pass full messages and tools arrays for more accurate simulation:

curl -X POST https://api.haimaker.ai/auto-router/{router_id}/simulate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": [
{"type": "text", "text": "What is in this image?"},
{"type": "image_url", "image_url": {"url": "https://example.com/photo.jpg"}}
]}
]
}'

Response:

{
"resolved_model": "anthropic/claude-sonnet-4-6",
"rule_id": "rule:rule-abc-123",
"reason": "example-match",
"similarity": 0.91,
"detected_capabilities": null,
"rule_similarities": [
{
"rule_id": "rule-abc-123",
"target_model": "anthropic/claude-sonnet-4-6",
"similarity": 0.91,
"match_threshold": 0.8,
"matched": true,
"skipped_reason": null
},
{
"rule_id": "rule-def-456",
"target_model": "openai/gpt-4o",
"similarity": 0.42,
"match_threshold": 0.8,
"matched": false,
"skipped_reason": null
}
]
}
FieldDescription
resolved_modelThe model that would handle the request
rule_id"rule:<id>" of the matched rule, or "default" / "capability-fallback"
reason"example-match", "capability-fallback", or "default"
similaritySimilarity score of the matched rule
detected_capabilitiesCapabilities detected in the request
rule_similaritiesPer-rule breakdown: score vs. threshold, and skipped_reason (disabled, capability-mismatch, not-initial-turn, target-not-capable, no-examples) when a rule wasn't eligible

Proposals (review queue and changelog)​

The tuner analyzes your captured traffic daily and proposes cheaper routes as rules. See Rules the router learns on its own for how proposals are generated and when they auto-apply.

List proposals​

# Review queue
curl "https://api.haimaker.ai/auto-router/{router_id}/proposals?status=pending" \
-H "Authorization: Bearer YOUR_API_KEY"

# Changelog
curl "https://api.haimaker.ai/auto-router/{router_id}/proposals?status=auto_applied,accepted,rejected,reverted" \
-H "Authorization: Bearer YOUR_API_KEY"

status accepts a comma-separated list of pending, auto_applied, accepted, rejected, reverted, expired. Omit it to get everything (newest first, up to 200).

Response (one entry):

{
"id": "prop-123",
"router_id": "router-abc",
"rule_id": null,
"status": "pending",
"cluster_examples": [
"Classify the sentiment of this review as positive, negative, or neutral: ...",
"Classify the sentiment of this review as positive, negative, or neutral: ..."
],
"cluster_stats": {
"weight": 1240,
"distinct_days": 6,
"tightness": 0.94,
"key_attribution": {"a1b2c3...": 0.98}
},
"judge_tier": "trivial",
"judge_task_type": "sentiment classification",
"judge_reasoning": "Single-label classification with a fixed output format; no reasoning depth required.",
"current_route": "default",
"proposed_model": "z-ai/glm-4.7-flash",
"projected_savings": 38.4,
"created_at": "2026-06-10T04:00:00Z",
"resolved_at": null,
"resolved_by": null,
"resolved_by_email": null
}
FieldDescription
cluster_examplesRepresentative prompts from the traffic cluster
cluster_statsVolume (weight), distinct_days, cluster tightness, and which API keys sent the traffic
judge_tiertrivial, standard, or complex
judge_reasoningWhy the judge rated it that way -- read this before accepting
current_routeWhere the traffic goes today (default, capability-fallback, or a rule)
projected_savingsEstimated monthly savings in USD, from the cluster's observed spend
resolved_byUser ID, or "auto" / "auto-revert" for tuner actions
resolved_by_emailEmail of the resolving user, when applicable

Pending proposals expire after 30 days if nobody acts on them.

Accept a proposal​

Creates the mined rule and records the decision in the changelog.

curl -X POST https://api.haimaker.ai/auto-router/{router_id}/proposals/{proposal_id}/accept \
-H "Authorization: Bearer YOUR_API_KEY"

Reject a proposal​

curl -X POST https://api.haimaker.ai/auto-router/{router_id}/proposals/{proposal_id}/reject \
-H "Authorization: Bearer YOUR_API_KEY"

Both return the updated proposal. Only pending proposals can be accepted or rejected.


Traffic summary​

Top captured prompt templates, for understanding what your router actually serves. Same data as the dashboard's Traffic tab.

curl "https://api.haimaker.ai/auto-router/{router_id}/traffic-summary?days=30" \
-H "Authorization: Bearer YOUR_API_KEY"

days is clamped to 1-30. Returns the top 50 templates by request count:

{
"days": 30,
"templates": [
{
"prompt_hash": "9f8e7d...",
"prompt_text": "HEARTBEAT: confirm agent liveness and report queue depth",
"weight": 4210,
"trigger": "rule:rule-abc-123",
"resolved_model": "z-ai/glm-4.7-flash"
}
]
}

prompt_text is the normalized template (volatile parts like timestamps stripped), truncated to 300 characters. trigger is default, capability-fallback, or rule:<id>. Returns empty templates if capture is disabled for the router.


Assign a router to a key​

To use auto-routing, assign a router to an API key via the auto_router_id field. Then requests with model: "haimaker/auto" will use that router.

curl -X POST https://api.haimaker.ai/key/update \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"key": "sk-key-to-update",
"auto_router_id": "router-id-here"
}'

Or assign during key creation:

curl -X POST https://api.haimaker.ai/key/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"team_id": "your-team-id",
"key_alias": "auto-routed-key",
"auto_router_id": "router-id-here"
}'

Query routing history​

Fetch spend logs to see how your auto-routed requests were resolved. See Auto-Router > Query routing history for full details.

curl "https://api.haimaker.ai/spend/logs/v2?start_date=2026-06-01&end_date=2026-06-08&page=1&page_size=50" \
-H "Authorization: Bearer YOUR_API_KEY"

Each entry includes auto-routing metadata in the metadata field: auto_routed_from, auto_routed_model, auto_routing_trigger, auto_routing_similarity, and auto_routing_rule_source.