Categorize products
Instead of hand-sorting ten thousand items, send your products with your own category tree, flat or nested, and get back the category path for each one. The tree travels with every batch, so a fashion store and a hardware distributor use the same tool. You pay per use.
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.
A supplier feed rarely matches your store's category tree, and no merchandiser wants to hand-sort ten thousand SKUs against a nested taxonomy.
Your category tree, not a built-in one
A supplier feed rarely matches your store's category tree, and nobody wants to hand-sort ten thousand items against a nested taxonomy. You send the products, each with a title, a description and optionally a brand or attributes, together with the taxonomy you already maintain, as a flat list or a nested tree. Each product comes back with the category path it belongs in. Because the taxonomy travels with what you send instead of being a fixed list, the same tool serves a fashion retailer's tree and a hardware distributor's tree without any retraining or setup on your side.
Where it saves the most sorting
New inventory becomes browsable and searchable the moment it lands, instead of sitting in an uncategorized bucket for a week. A marketplace can map a new seller's raw feed onto its taxonomy before the listings go live; a distributor sync can reconcile a supplier's category names with the internal tree every time the price and stock feed updates; a cleanup project can re-categorize a legacy catalog against a redesigned tree in one batch rather than a manual re-tagging sprint. Products described in another language or convention fit into your existing structure without building a translation step first.
What you can do with it
Marketplace seller onboarding
Map a new seller's raw product feed onto your marketplace taxonomy automatically before their listings go live.
Distributor catalog syncs
Reconcile a supplier's category names with your internal tree every time a price-and-stock feed updates.
PIM cleanup projects
Re-categorize a legacy catalog against a redesigned taxonomy in one batch instead of a manual re-tagging sprint.
Cross-border catalog expansion
Fit products described in another language or convention into your existing category structure without building a translation layer first.
FAQ
Can I use a nested category tree, not just a flat list?
Yes, both flat lists and nested trees are supported, and the response includes the full category path for each product.
Is there a free trial?
There's no free tier — free tiers get abused and slow everyone down. No subscription, no tokens, no invented credits, and a failed task is never charged.
Can I send bulk batches for a whole catalog import?
Yes, bulk feeds are the typical use case; send the full product array in one call and pricing scales per item with no arbitrary cap.
Does it work for catalogs in Spanish or other languages?
Yes, the model reads the title and description in the language you send and maps them to your taxonomy regardless of the language the category names are written in.
What do I need to send with each product?
A title and a description, optionally a brand or attributes, plus your category structure as a flat list or a nested tree. That is enough for each product to come back with the category path it belongs in.
Related tools
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, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/text/product-categorize \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"El informe trimestral cerró con 1,2 M€ de ingresos.","taxonomy":["electrónica > audio","hogar > cocina"]}'const res = await fetch("https://api.kit.forhosting.com/text/product-categorize", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "El informe trimestral cerró con 1,2 M€ de ingresos.",
"taxonomy": [
"electrónica > audio",
"hogar > cocina"
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/text/product-categorize",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "El informe trimestral cerró con 1,2 M€ de ingresos.",
"taxonomy": [
"electrónica > audio",
"hogar > cocina"
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/text/product-categorize", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"El informe trimestral cerró con 1,2 M€ de ingresos.","taxonomy":["electrónica > audio","hogar > cocina"]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"El informe trimestral cerró con 1,2 M€ de ingresos.","taxonomy":["electrónica > audio","hogar > cocina"]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/text/product-categorize", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "El informe trimestral cerró con 1,2 M€ de ingresos.",
"taxonomy": [
"electrónica > audio",
"hogar > cocina"
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "text.product_categorize",
"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. |
Technical notes
This endpoint takes a product title, description or attribute list and returns the category path it belongs in, so new inventory is browsable and searchable the moment it lands rather than sitting in an 'uncategorized' bucket for a week.
The problem this solves
Doing that by hand for a few dozen items is fine; doing it for a rolling feed of thousands is a full-time job nobody wants, and it's exactly the gap product categorization closes.
What the request looks like
You send an array of products — title, description, and optionally brand or attributes — plus your taxonomy (a flat list or a nested tree) to /text/product-categorize.
Where it plugs into your pipeline
Because your taxonomy is part of the request, not a fixed built-in list, the same endpoint serves a fashion retailer's tree and a hardware distributor's tree without retraining or reconfiguring anything on your side — you simply pass the structure you already maintain. Feed ingestion jobs, PIM syncs and marketplace onboarding flows can call it as one step in a larger pipeline, with the webhook triggering the next stage automatically.
Technical questions
How does the product categorization API map items to my taxonomy?
You include your taxonomy in the request, and each product's title, description and attributes are matched against it to return the best-fit category node, with a runner-up when the call is close.
What does it cost to categorize a large catalog?
$0.003 per request plus $0.0135 per item, so categorizing 5,000 SKUs has a fixed, calculable cost regardless of how nested your taxonomy is.
How are results delivered?
The task runs asynchronously; you get a task_id immediately and the categorized results via your signed webhook or a signed link valid for 24 hours.
What happens with ambiguous products?
They're returned with their best-fit category and a runner-up alternative instead of a single overconfident guess, so a merchandiser can resolve the edge cases quickly.