Translate with a glossary
A generic translator will happily render the same product name three different ways in the same document, because it has no idea that word is off-limits. This endpoint accepts a glossary alongside the text and locks specific terms to the translations you define, so your brand name, your legal term and your product feature stay exactly as written.
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 word that keeps changing when it shouldn't
A software company calls its core feature 'Workspace' in English and wants it to stay 'Workspace' — untranslated — in every language, because it's a proper noun inside the product UI. A law firm needs 'sociedad anónima' to always map to a specific fixed phrase in English, not whatever synonym a model reaches for that day. A medical device manufacturer has a list of component names that must match its regulatory filings word for word. General-purpose translation has no way to know any of this unless it's told, and telling it once per document isn't reliable — it has to be enforced every time.
How the glossary actually gets applied
POST /translate/glossary with the source text, target language, and a glossary of source-term to target-term pairs; a task_id comes back immediately and the job runs asynchronously like the rest of the translation endpoints. During translation, every occurrence of a glossary term is forced to its defined translation instead of being left to the model's judgment, while everything else around it is translated normally — so the sentence still reads naturally, it just never drifts on the terms that matter.
Why glossaries exist as a translation concept at all
Controlled terminology predates machine translation by decades — technical writers and localization teams have kept termbases for enterprise software and pharmaceutical documentation since long before automated translation was reliable, precisely because consistency in specialized vocabulary can't be left to chance or to a translator's personal preference. A glossary is the same idea applied to an API call: instead of hoping the output happens to match your style guide, you supply the mapping and the translation is constrained to follow it, term by term, document after document.
Fitting it into a real terminology workflow
Teams that maintain a style guide or a termbase already have the raw material for a glossary sitting in a spreadsheet somewhere; feeding that list into /translate/glossary turns a static reference document into an active constraint on every translation that goes through the pipeline. Because pricing is a small flat fee plus a per-1000-word rate, running the same glossary against a growing set of documents — release notes, contracts, product descriptions — stays predictable even as the glossary itself grows to cover more terms over time.
What you can do with it
Product and feature names
A software company forces feature names like a proprietary product name to stay untranslated and consistent across every localized version of its help center.
Legal term consistency
A law firm enforces a fixed English rendering for recurring local legal terms so every translated contract uses identical phrasing instead of varying synonyms.
Regulated component naming
A medical device manufacturer locks translated component names to match exactly what's filed with regulators, avoiding mismatches that could delay approval.
Brand voice across markets
A retail brand keeps its slogan and category names identical in every market by supplying them as fixed glossary entries instead of leaving them to translation.
FAQ
How does glossary-based translation work in the API?
POST your text, target language and a list of source-to-target term pairs to /translate/glossary; the returned task_id lets you retrieve the finished translation by webhook or a signed link valid for 24 hours.
Is the glossary translation API free?
No, there is no free tier or trial; it costs $0.003 per request plus $0.0135 per 1000 words, and a failed job is never charged.
Does the glossary override the model completely for those terms?
Yes, any glossary term found in the source text is forced to your defined translation rather than left to the model's own choice.
How many glossary terms can I include?
You can submit as many source-to-target pairs as your terminology requires; larger glossaries don't change how the endpoint is called, only the mapping it enforces.
Can I use a different glossary per language pair?
Yes, since the glossary is submitted with each request, you can pair a different termbase with each target language as needed.
Is this different from translate with formality or tone-preserve?
Yes, glossary translation constrains specific terms to fixed output; formality and tone-preserve control the register and voice of the surrounding text instead.
Can I run glossary translation on many documents at once?
Yes, submit one asynchronous task per document with the same glossary attached, and collect each result by webhook as it finishes.
Is my glossary or text stored afterward?
No, submitted text and glossary data are deleted after the retention window and are never used for training.
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/translate/glossary \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"…"}'const res = await fetch("https://api.kit.forhosting.com/translate/glossary", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/translate/glossary",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/translate/glossary", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/translate/glossary", 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": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "translate.glossary",
"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. |