Route tickets
A billing question sitting in the engineering queue costs a customer patience and costs a company a slower resolution than it should ever take. This endpoint reads the actual text of a support ticket and routes it to the queue, team or priority it belongs in, before a triage agent ever has to open it.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The cost of a mis-routed ticket
Every support team has watched a ticket bounce between two or three queues before landing where it should have started — a customer re-explains their problem, an agent closes it as 'not my team', and the clock keeps running against a resolution-time target that was never really broken by the customer, just by the routing. This endpoint exists to catch that at the door.
How it decides
You POST the ticket's subject and body, and the task reads the language for the actual problem being described — billing, bug report, feature request, account access, abuse — along with signals like urgency and customer tone, then returns a suggested queue, category and priority. It doesn't rely on the customer picking the right dropdown, because most don't.
Built for support operations at any size
A two-person support team fields everything themselves and mainly needs priority sorted, not queue routing — this still helps them triage urgent from routine. A larger operation with specialized teams for billing, technical issues and account security needs the routing itself, so a ticket about a failed payment never lands on an engineer's desk. Either way, it removes a manual first pass that adds no real value once it's been done a thousand times.
Ticket queues are older than the ticket, in a sense
Support queues borrow their structure from call-center routing, where a caller pressing '2 for billing' was doing manually what modern routing tries to do from raw text instead — because most customers don't know or care which internal team owns their problem, they just want it solved, and forcing them through a menu of departments they don't understand was always a workaround, not a solution.
Where it plugs into a support stack
Because results return as structured JSON via webhook, the suggested queue and priority write straight into whatever helpdesk tool a team already uses, updating the ticket's fields the moment it arrives rather than waiting for a human to glance at it first.
What you can do with it
Splitting billing from technical support
A SaaS support desk automatically separates payment and subscription questions from bug reports so each reaches the team equipped to answer it.
Surfacing urgent tickets early
A team with a shared inbox uses the priority signal to pull genuinely urgent issues — outages, security concerns — to the top before anything else is touched.
Reducing re-routes between teams
A growing support org cuts down on tickets bouncing between queues by routing based on what the ticket actually says instead of a customer-picked category.
Triage for a lean support team
A two-person team without dedicated queues still uses the routing output to sort urgent from routine before starting their day.
FAQ
How does the ticket routing API work?
You POST a ticket's subject and body to /text/ticket-route, the task runs asynchronously, and you receive a suggested queue, category and priority via webhook or signed link.
Is there a free trial?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
Can it route to custom queues specific to my helpdesk?
Yes, you can pass your queue and category definitions as context so the routing maps to the structure you already use.
Does it also set ticket priority?
Yes, priority is returned alongside the suggested queue based on urgency and tone signals in the ticket text.
What happens if a ticket doesn't fit any queue cleanly?
The task returns its best match along with the reasoning, so an agent can quickly confirm or reassign it rather than starting from zero.
Am I charged for failed routing tasks?
No. Tasks are retried automatically up to three times on failure and are never charged; you pay only for tickets actually routed.
Can I route tickets in bulk?
Yes, pricing includes a per-request cost plus a per-ticket cost, so batches of tickets can be routed together.
How does this compare to keyword-based routing rules?
Keyword rules break on phrasing they weren't written for; this endpoint reads the actual meaning of the ticket text, catching cases a fixed keyword list would miss.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/text/ticket-route \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/text/ticket-route", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"input": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/text/ticket-route",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"input": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/text/ticket-route", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"input":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"input":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/text/ticket-route", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"input": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "text.ticket_route",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_tokens | 20000 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |