Image translation API: send an image, get a translated image back
The TranslateMyImage API translates the text inside an image and returns a new image, not a list of strings. You send one image and one target language to a single endpoint; the JSON response contains a URL to the translated image, generated to keep the original layout. This page shows what the API does, request examples in curl, Python and Node.js, how to handle errors, and when building your own OCR pipeline makes more sense. The full reference is in the API documentation.
In short
- One endpoint:
POST https://translatemyimage.com/api/translatewith anX-API-Keyheader and a multipart body containing the image andtarget_lang. - One request = one image into one language = one credit when it completes. Target languages: en, fr, es, de, it, pt, ja, ko, zh.
- API access starts with the Pro plan (Pro, Premium or Enterprise). Review generated images before you publish them.
Request fields
The body is multipart/form-data, which your HTTP client sets for you.
| Field | Required | Accepted values |
|---|---|---|
file | Yes | A JPG, PNG or WEBP image, up to 10 MB and 25 megapixels |
target_lang | Yes | en, fr, es, de, it, pt, ja, ko or zh |
source_lang | No | One of the nine codes above; omit it or send auto to auto-detect |
quality | No | basic (default) or ultra |
business_type | No | default, marketing, edition (the Manga/Comics mode) or technical documentation |
custom_prompt | No | Instructions for the model, up to 1,000 characters (Pro plan and above) |
Response
A successful call returns this shape (example from the reference):
{
"success": true,
"translation": {
"id": "clxb1234567890",
"originalUrl": "https://storage.com/original.jpg",
"translatedUrl": "https://storage.com/translated.jpg",
"sourceLang": "fr",
"targetLang": "en",
"status": "completed",
"createdAt": "2026-09-21T15:27:39.000Z",
"metadata": { "quality": "basic", "model": "muse-image" }
}
}
sourceLang is null when you omit source_lang or send auto. Errors return JSON with success: false, an error message and, once the key is accepted, a stable code such as insufficient_credits.
Quick start
Create a key on the dashboard's API Keys page. It is shown only once, so store it in an environment variable or a secret manager right away.
curl
curl -X POST https://translatemyimage.com/api/translate \
-H "X-API-Key: $TMI_API_KEY" \
-F "[email protected]" \
-F "target_lang=es" \
-F "source_lang=auto" \
-F "business_type=marketing"
Python (requests), with a retry when the image service is rate limited:
import os
import time
import requests
API_URL = "https://translatemyimage.com/api/translate"
API_KEY = os.environ["TMI_API_KEY"]
def translate_image(path, target_lang, business_type="default", max_attempts=5):
for attempt in range(max_attempts):
with open(path, "rb") as image:
response = requests.post(
API_URL,
headers={"X-API-Key": API_KEY},
files={"file": image},
data={
"target_lang": target_lang,
"source_lang": "auto",
"business_type": business_type,
},
timeout=900, # generation can take minutes: keep this generous
)
if response.status_code == 429:
time.sleep(2 ** attempt) # exponential backoff, then retry
continue
payload = response.json()
if response.status_code != 200 or not payload.get("success"):
raise RuntimeError(f"{response.status_code}: {payload.get('error')}")
return payload["translation"]
raise RuntimeError(f"Still rate limited after {max_attempts} attempts")
for lang in ["es", "fr", "de"]:
result = translate_image("product-front.jpg", lang, "marketing")
print(lang, result["translatedUrl"])
Node.js (18 or later, as an ES module, with the built-in fetch and FormData):
import { readFile } from "node:fs/promises";
const form = new FormData();
const image = new Blob([await readFile("product-front.jpg")], { type: "image/jpeg" });
form.append("file", image, "product-front.jpg");
form.append("target_lang", "ja");
const response = await fetch("https://translatemyimage.com/api/translate", {
method: "POST",
headers: { "X-API-Key": process.env.TMI_API_KEY },
body: form,
});
const payload = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${payload.error}`);
console.log(payload.translation.translatedUrl);
One target_lang per request: to translate an image into five languages, send five requests.
Handle every status code
| Status | Meaning (from the reference) | What your code should do |
|---|---|---|
| 200 | Translation completed; one credit consumed | Download and store the translated image |
| 400 | Invalid input, unsupported format or missing file | Do not retry. Validate type, size (10 MB), resolution (25 MP) and language code before sending |
| 401 | Missing, invalid or revoked API key | Do not retry. Check the key and how it is loaded |
| 403 | The account that owns the key is not on the Pro plan or above, which API access requires | Do not retry. Check the plan of the account that created the key |
| 429 | The image service is rate limited | Retry later with exponential backoff |
| 500 | Processing failed | Check code first: insufficient_credits means the account needs credits, so a retry will not help. Otherwise retry once or twice, then log the file for manual handling |
The reference documents these six statuses. The endpoint can also return others, for example 422 when no image could be generated (code: generation_failed) or 503 when the image service is unavailable (service_unavailable), so branch on code rather than on the status alone.
Build it yourself or call an image-to-image API?
Instead of an image-to-image API, you can assemble a pipeline: an OCR service to find the text (Google Cloud Vision, for example, returns the extracted text with the bounding box of each word, per its OCR documentation), a text translation API, then code that erases the original text and typesets the translation in the same boxes with a matching font.
| OCR + text translation + your own rendering | TranslateMyImage API | |
|---|---|---|
| What you get | Text strings with coordinates, then whatever you render | A URL to a finished translated image |
| Control | Full: fonts, enforced glossaries, editable layers | Mode (business_type) and custom_prompt |
| Engineering effort | Several services plus rendering code to build and maintain | One HTTP request per image and language |
| Target languages | Whatever your translation service supports | 9 |
| Translated text as data | Yes | No, the API returns an image |
| Pixels outside the text | Untouched | Regenerated with the image: digits, small text and logos can change |
Build it yourself when you need the translated text as data (alt text, search), strict terminology enforcement, editable layers, more languages, or pixels outside the text that must stay identical. Call the API when you want finished visuals in a few languages and can review them before use.
A production workflow
- Validate locally before sending: file type, 10 MB, 25 megapixels, a supported
target_lang. - Queue one job per image and language, and back off on 429.
- Copy the result to your own storage or DAM with the source ID, target language,
translation.idandcreatedAt. Neither the reference nor the privacy policy promises how longtranslatedUrlstays available, so do not rely on it as permanent hosting. It is an unsigned storage link: treat it as public. - Mark every output "to review". A person who reads the target language checks prices, specifications and legal text first, then headlines. The batch translation page has a review-by-risk table you can reuse.
- Publish only reviewed images, for example to your Amazon listing images.
Before writing code, run a few representative images through the web uploader with the mode you plan to use. For occasional jobs without code, batch translation in the dashboard is simpler: up to 10 images and 50 translated outputs per batch.
Plans and credits
API access is included from the Pro plan up: Pro comes with 100 credits a month and Premium with 300 (pricing). Each completed translation consumes one credit. Pay-as-you-go packs add 1 credit for $2, 30 for $10 or 100 for $20; they do not unlock API access on their own. Every plan with API access also includes Ultra quality and custom_prompt.
Read the API reference
Endpoint, headers, parameters, status and error codes, an example response and calls in cURL, Python and Node.js.
Frequently asked questions
Is there an API that translates the text inside an image?
Yes. The TranslateMyImage API takes an image and a target language and returns a URL to a new image with the text translated, generated to keep the original layout. With a text translation API, you would first extract the text from the image with OCR and then draw the translation back yourself.
Does the API return the translated text?
No. The response contains the translation's ID, the original and translated image URLs, the languages, a status, a timestamp and metadata. If you need the translated text itself, for alt text or search, run an OCR service on the translated image.
Can I translate one image into several languages in one request?
No. Each request has one target_lang. To get five languages, send five requests with the same file; each completed translation uses one credit.
How much does the image translation API cost?
Each completed translation consumes one credit. API access is included from the Pro plan up: Pro costs $9.90 a month with 100 credits, Premium $19.90 a month with 300 credits. Pay-as-you-go packs add credits (1 for $2, 30 for $10 or 100 for $20) but do not unlock API access on their own.
Is there a Python or JavaScript SDK?
The reference documents plain HTTP calls, with examples in cURL, Python (requests) and Node.js (axios). Any HTTP client that can send multipart/form-data with a custom header works.