Translate text in a photo
Send a photo of a restaurant menu taken in Tokyo and you get back the recognized Japanese text and its translation together, with no separate reading step and no retyping. It works on signs, scanned contracts, product labels and support screenshots.
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.
No separate OCR step, no manual retyping.
Why text in a photo needs reading first
Most translation tools expect clean, selectable text, but a large share of real-world text never arrives that way. It is baked into a photo of a sign, a scanned contract, a screenshot attached to a support ticket or a label shot on a warehouse floor. Before any of it can be translated it has to be recognized, and recognition quality depends heavily on lighting, angle, font and image resolution. A blurry, tilted photo of small print is read less reliably than a sharp, straight shot, so retaking the picture in better light is the simplest way to improve a result.
What you get back and where it helps
You send an image and the language you want; the text visible in it is extracted first and then translated. The answer contains both the recognized source text and its translation, so you can check what was read before trusting what was translated. A traveler can photograph a menu abroad and understand it at once, a support team can read a screenshot written in a language nobody on the team knows, a seller can translate labels from an overseas supplier's packaging before listing a product, and an inspector can confirm that a safety placard matches the required wording. Large images may take a moment, and the finished result stays available through a link for 24 hours.
What you can do with it
Travel apps
A traveler photographs a menu abroad and the app shows an instant translated overlay without the user typing a single word.
Support ticket triage
A customer support tool automatically translates screenshots that non-native-speaking users attach to tickets, so agents don't need to guess.
Cross-border e-commerce
A seller translates product labels photographed from an overseas supplier's packaging before listing the item in a new market.
Field compliance checks
An inspection app reads and translates safety placards photographed on-site to confirm they match required wording.
FAQ
What image formats are accepted?
Standard photo and screenshot formats work; the task is built for real-world photos, not just clean scans, including tilted or low-light shots.
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 bulk translate many photos at once?
Yes, each image is submitted as its own async request and billed independently, which suits batch pipelines well.
How accurate is the text recognition?
Accuracy depends on image quality — angle, lighting and resolution all matter — but the task is designed for typical real-world photos, not just studio scans.
What if the OCR or translation step fails?
The task retries automatically up to three times and is never billed on failure; you get a clear error after retries are exhausted.
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/translate/ocr \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"image":"https://ejemplo.com/imagen.jpg","target_lang":"en"}'const res = await fetch("https://api.kit.forhosting.com/translate/ocr", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"image": "https://ejemplo.com/imagen.jpg",
"target_lang": "en"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/translate/ocr",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"image": "https://ejemplo.com/imagen.jpg",
"target_lang": "en"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/translate/ocr", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"image":"https://ejemplo.com/imagen.jpg","target_lang":"en"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"image":"https://ejemplo.com/imagen.jpg","target_lang":"en"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/translate/ocr", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"image": "https://ejemplo.com/imagen.jpg",
"target_lang": "en"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "translate.ocr",
"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
A restaurant menu photographed in Tokyo, a warning label shot on a factory floor, a screenshot of a chat in a language your support team doesn't read — this endpoint reads the pixels first, then translates what it finds, in a single call.
Text trapped in pixels
Most translation tools expect clean, selectable text, but a huge share of real-world text never arrives that way: it's baked into a photo of a sign, a scanned contract, a screenshot shared in a support ticket, or a product label shot on a warehouse floor. Before that text can be translated it first has to be recognized, and recognition quality depends heavily on lighting, angle, font and image resolution — which is exactly the part this endpoint absorbs so the caller doesn't have to stitch two tools together.
One call, two steps under the hood
Send POST /translate/ocr with an image and a target language, and the task first extracts the visible text with optical character recognition, then runs that text through translation, returning both the recognized source text and its translation. Because it's asynchronous, the response is a task_id, and the finished result lands via signed webhook or a signed link kept alive for 24 hours — useful when the image is large or the queue is busy.
A brief note on OCR itself
Optical character recognition dates back to devices built for reading printed numerals in the mid-20th century, long before it became the background technology inside scanners, license-plate readers and phone camera apps; what's changed since is that modern recognition handles messy, real-world photos — skewed angles, mixed fonts, low light — rather than only clean scans, which is what makes photo-to-translation pipelines practical today instead of a lab curiosity.
Where this earns its keep
Travel and hospitality apps translating menus and signage from a user's photo, customer support teams handling screenshots in foreign languages, e-commerce sellers translating product labels and packaging photos from overseas suppliers, and compliance teams reading safety placards or shipping documents captured in the field.
Fitting into a larger workflow
Because the task is billed only on success, with three automatic retries before a clear failure is reported, it's safe to wire directly into an intake pipeline, a support-ticket bot, or a mobile app's photo-upload flow without babysitting retries by hand. Pricing is transparent and additive — a $0.011 base per request plus $0.0705 per image processed — so cost scales predictably with volume rather than hiding behind bundled credits.
Technical questions
How does the image translation API actually work?
It runs optical character recognition on the image to extract the visible text, then translates that text into the target language, returning both in one response.
How much does it cost to translate text in an image?
A base of $0.011 per request plus $0.0705 per image processed, published upfront with no hidden credits.
How do I receive the translated result?
Via a signed webhook when the task completes, or a signed link valid for 24 hours if you prefer to pull it.