Back-translate to check
The fastest way to find out whether a translation actually says what you think it says is to translate it back and read it in your own language again. The Back-Translation QA API takes a translated text plus its original, runs the reverse pass, and flags where the round trip drifted — a phrase that lost a negation, a number that got mangled, an instruction that turned vague. It's a quality check, not a rewrite, and it's built to sit inside a review step rather than replace one.
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.
Why translation errors hide in plain sight
A mistranslation rarely looks wrong on its own — it reads as perfectly fluent text in the target language, which is exactly why it's dangerous. A dosage instruction, a contract clause or a safety warning can shift meaning subtly enough that no one reviewing only the translated version would notice. Back-translation exposes that drift by forcing the meaning through the round trip and comparing what came out to what went in.
How the comparison works
Send the original text, the translation to verify, and their respective languages. We translate the translation back into the source language and return both the back-translated text and a structured comparison highlighting where meaning diverged — additions, omissions, sign flips on negatives, or numbers and names that changed. You get a diff you can act on, not just a second translation to read side by side.
A technique older than machine translation
Back-translation predates automated translation entirely — it's a standard method in clinical trial documentation and cross-cultural survey research, where a mistranslated question can silently invalidate results. The logic transfers directly to software localization and legal text: if the round trip preserves meaning, the translation is very likely sound; if it doesn't, you know exactly where to look.
Fitting it into a review pipeline
Call the endpoint asynchronously after your translation step completes, get a task_id back right away, and receive the comparison via signed webhook or a signed link valid for 24 hours. Because it's decoupled from the translation call itself, you can run it selectively — every string, or only the high-risk ones like legal, medical or pricing content.
What it won't do
It doesn't grade fluency or style, and a technically faithful back-translation can still read awkwardly in the target language — that's a separate, subjective judgment for a human reviewer. What it reliably catches is meaning drift: the kind of error spellcheck and grammar tools were never built to see, and the kind that only surfaces once a document is already in front of the wrong audience.
What you can do with it
Clinical and consent documentation
A patient consent form translated into a new language gets back-translated before use to confirm no clause changed meaning during translation.
Contract and legal review
A vendor agreement translated for a foreign partner is checked with back-translation to catch any clause where obligations or dates might have shifted.
E-commerce product data at scale
Thousands of product descriptions translated in bulk get spot-checked automatically, flagging the handful where numbers, sizes or warnings drifted.
Survey and research instruments
A questionnaire translated for a new market region is verified so the translated question still measures the same thing as the original.
FAQ
What is back-translation and why use this API for it?
Back-translation means translating a translated text back into its original language to check whether the meaning survived the round trip; this API automates that check and returns a structured comparison instead of just a second translation.
Is it free to try?
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.
How much does it cost?
$0.003 per request plus $0.0135 per 1,000 words, and you're only billed for tasks that complete successfully.
Does it fix the translation for me?
No, it flags where meaning diverged so a human or another process can decide how to correct it; it's a QA step, not a rewriting tool.
Can it check any language pair?
Yes, submit the source language and the translation's language and we run the reverse pass between them.
How do I get the comparison result?
Through a signed webhook, recommended for automated pipelines, or a signed link valid for 24 hours if you'd rather retrieve it manually.
Should I run this on every translated string?
It depends on risk — many teams run it selectively on legal, medical or pricing content and skip it on low-stakes marketing copy where the cost isn't justified.
What happens on failure?
We retry automatically up to three times; a persistent failure returns a clear error and is never charged.
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/back \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"…"}'const res = await fetch("https://api.kit.forhosting.com/translate/back", {
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/back",
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/back", 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/back", 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.back",
"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. |