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.
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-20250514"
},
{
"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
| Field | Type | Description |
|---|---|---|
rule_order | int | Priority (lower = higher priority; breaks similarity ties) |
example_prompts | string[] | Example prompts that define what this rule matches (max 50). Embedded server-side. |
match_threshold | float | Minimum similarity (0-1) for the rule to fire. Omit for the default, 0.8. |
required_capabilities | string[] | Only fire when the request needs these capabilities |
initial_turn_only | bool | Only match on the first message in a conversation |
enabled | bool | Disabled rules are kept but never match (default true) |
target_model | string | Model 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.
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-20250514",
"capture_enabled": true,
"auto_apply_enabled": false
}'
| Field | Description |
|---|---|
capture_enabled | Store normalized prompts for tuning and the Traffic tab (30-day retention). Set false to opt out -- the router stops learning. |
auto_apply_enabled | Let 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-20250514"
}'
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-20250514"
}'
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-20250514",
"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-20250514",
"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
}
]
}
| Field | Description |
|---|---|
resolved_model | The 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" |
similarity | Similarity score of the matched rule |
detected_capabilities | Capabilities detected in the request |
rule_similarities | Per-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
}
| Field | Description |
|---|---|
cluster_examples | Representative prompts from the traffic cluster |
cluster_stats | Volume (weight), distinct_days, cluster tightness, and which API keys sent the traffic |
judge_tier | trivial, standard, or complex |
judge_reasoning | Why the judge rated it that way -- read this before accepting |
current_route | Where the traffic goes today (default, capability-fallback, or a rule) |
projected_savings | Estimated monthly savings in USD, from the cluster's observed spend |
resolved_by | User ID, or "auto" / "auto-revert" for tuner actions |
resolved_by_email | Email 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.