Creator Tools Translator API: Developer Guide
This guide explains how to translate YouTube videos and channels with the Creator Tools translator from your own code. New to the API? Start with the overview: The Creator Tools Translator Is Now Available by API.
Overview
- Translation runs as a background job. You start a job, get a
jobIdback, and then check the job until it is done. - Starting a job and checking it use the same address:
POST https://api.creator-tools.com/info/longterm-job. TherequestTypefield in the body says which one you want. - When the job finishes, the translated title, description and subtitles are already published on YouTube.
- There are no callbacks. Check the job status every 5 seconds, the same way the Creator Tools app does.
1. POST /info/longterm-job { "requestType": "startTranslationJob", … } → { "jobId": "…", "status": "IN_PROGRESS" }
2. POST /info/longterm-job { "requestType": "getJobById", "jobId": "…" } → { "status": "IN_PROGRESS" }
… wait 5 seconds, repeat …
3. POST /info/longterm-job { "requestType": "getJobById", "jobId": "…" } → { "status": "FINISHED", "response": { … } }
Keys You Need
Every request needs four values. You get the gateway key from the support team once. The other three you copy from your browser while you are logged in to https://app.creator-tools.com; the next chapter shows where they are.
| Value | Send as | Where to find it |
|---|---|---|
| Gateway key | Header x-api-key | Ask the support team for it: write to info@creator-tools.com or to the Creator Tools bot in Telegram. |
| Personal key | Body field xApiKey | Developer tools → Application → Cookies → https://app.creator-tools.com → cookie xApiKey. This is your subscription key: translations are taken from your balance. |
| Session ID | Body field sessionId | Developer tools → Application → Local storage → https://app.creator-tools.com → key channels |
| Channel ID | Body field channelId | The same channels entry |
All requests are POST with Content-Type: application/json. No cookies or Authorization header are needed.
Keep your keys private. Your personal key and session ID work like a password: anyone who has them can start translations on your channel and spend your balance. Never put them in public code or share them in chats.
Finding Your Session ID and Channel ID
Step 1: Log In and Pick the Channel
Open https://app.creator-tools.com, log in, and select the channel you want to translate in the channel list. If the channel is not there yet, add it first with Add channel.
Step 2: Open Local Storage
Open the developer tools (F12 on Windows, ⌥⌘I on Mac) → Application → Local storage → https://app.creator-tools.com → key channels.
The value has one entry for each connected channel. The name of the entry is the channel ID, and the entry holds the session ID:
{
"UCzOmbH8UyFIVjSAukXAhY5g": { // ← channelId
"sessionId": "f35876a8-1…", // ← sessionId
"channelId": "UCzOmbH8UyFIVjSAukXAhY5g",
"name": "My Channel",
"isSelected": true // ← the channel picked in the app
},
"UC…another channel…": { … }
}
If you have several channels, use the entry with "isSelected": true, or the one whose name matches the channel you want.
Good to Know
- The channel ID is the YouTube channel ID that starts with
UC. The session ID is created by Creator Tools when you connect the channel. - A channel connection lasts about three months. If you get
403 No credentials for channel, remove the channel in the app, add it again, and copy the new session ID. - Logging out of the app ends the session, so the old session ID stops working.
Start a Translation
POST https://api.creator-tools.com/info/longterm-job
Headers: Content-Type: application/json and x-api-key: <gateway key>.
Translate one video at a time. Start a job, check it until its status is FINISHED or FAILED, and only then start the next video. Parallel jobs share your balance and your channel's YouTube limits, so they can be charged incorrectly, fail with 429, or overwrite each other's translations.
What Gets Translated
- With
videoId: the video's title and description, plus subtitles ifcapturesIncludedistrue. - Without
videoId: the channel's name and description.
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
xApiKey | string | yes | Your personal key |
requestType | string | yes | Always "startTranslationJob" |
sessionId | string | yes | Your session ID. Without it the reply is 400 Missing sessionId. |
channelId | string | yes | Your channel ID. It must belong to the same session; otherwise the reply is 403. |
languages | string[] | yes | Target language codes (see Languages and Codes). Languages the video already has are skipped unless rewrite is true. |
videoId | string | no | YouTube video ID. Leave it out to translate the channel. |
capturesIncluded | boolean | no | Also translate subtitles |
rewrite | boolean | no | Overwrite translations and subtitles that already exist |
saveHashtags | boolean | no | Keep #hashtags and @mentions as they are |
excludedFromTranslate | boolean | no | Keep text inside [[…]] untranslated |
useDialects | boolean | no | Translate regional variants (en-GB, es-MX, …) separately. When false, they get the translation of their main language. |
tone | string | no | default, emotional, friendly, science or official |
provider | string | no | openai (default) or gemini. If one fails, the other is tried, then Google Translate. |
isPoetry | boolean | no | Translate subtitles as a song or poem |
aiTranslations | boolean | no | Use AI translation. The app always sends true. |
Example: One Video with Subtitles
curl -X POST https://api.creator-tools.com/info/longterm-job \
-H 'Content-Type: application/json' \
-H 'x-api-key: <GATEWAY_KEY>' \
-d '{
"xApiKey": "<PERSONAL_KEY>",
"requestType": "startTranslationJob",
"sessionId": "<SESSION_ID>",
"channelId": "UCxxxxxxxxxxxxxxxxxxxxxx",
"videoId": "dQw4w9WgXcQ",
"languages": ["es", "de", "fr", "pt-BR", "ja"],
"capturesIncluded": true,
"rewrite": false,
"saveHashtags": true,
"excludedFromTranslate": false,
"useDialects": false,
"tone": "default",
"provider": "openai",
"isPoetry": false,
"aiTranslations": true
}'
Reply
A 200 reply describes the new job. Keep the jobId: you need it to check the job.
{
"jobId": "3f1c2a0e-7b8d-4c1e-9a55-…",
"jobType": "translate",
"videoId": "dQw4w9WgXcQ",
"channelId": "UCxxxxxxxxxxxxxxxxxxxxxx",
"status": "IN_PROGRESS",
"languages": ["es", "de", "fr", "pt-BR", "ja"],
"startDate": "2026-09-30T10:15:00.000Z"
}
Check the Job Status
POST https://api.creator-tools.com/info/longterm-job, with the same headers as above.
{
"xApiKey": "<PERSONAL_KEY>",
"requestType": "getJobById",
"jobId": "3f1c2a0e-7b8d-4c1e-9a55-…"
}
The 200 reply is the job, or null if you have no job with that ID.
{
"jobId": "3f1c2a0e-…",
"jobType": "translate",
"status": "FINISHED",
"startDate": "2026-09-30T10:15:00.000Z",
"finishDate": "2026-09-30T10:16:12.000Z",
"languages": ["es", "de", "fr", "pt-BR", "ja"],
"languagesToTranslateVideo": ["es", "de", "fr", "pt-BR", "ja"],
"languagesToTranslateCaptions": ["es", "de", "fr", "pt-BR", "ja"],
"response": {
"status": "translated",
"captionsTranslated": true,
"metadataLanguagesTranslated": 5,
"captionsLanguageTranslated": 5
}
}
Status Values
| Status | Meaning |
|---|---|
WAITING | The job is queued and has not started yet. |
IN_PROGRESS | The job is running. Keep checking. |
FINISHED | Done. The result is in response. |
FAILED | The job stopped. reason says why, for example no token, No Subscription, Not enough translations are left or freeTrialCheck failed. |
- How often to check: every 5 seconds. The app stops waiting after 50 minutes.
- No progress percentage: translation jobs report only their status.
- All your jobs: send
"requestType": "getAllJobs"with yourxApiKeyto list every job. - How long jobs are kept: a finished job can be read for 60 days.
Errors
An error reply has the form {"message": "…"}.
| HTTP | Message | What to do |
|---|---|---|
| 400 | Missing sessionId | Add sessionId to the request. |
| 403 | No credentials for channel | The session ID and channel ID don't match, or the connection has expired. Reconnect the channel in the app and copy the new session ID. |
| 403 | No subscription | The personal key xApiKey is wrong. Copy it again. |
| 403 | No access | The subscription could not be checked. Try again later. |
| 403 | Forbidden | The x-api-key header is missing or wrong. |
| 429 | Not enough translations are left | Your balance is too low for the chosen languages. Top up or pick fewer languages. |
A job can be accepted and still end as FAILED later, for example when the balance runs out during translation. Always check status and reason.
Full Example in JavaScript
const API = "https://api.creator-tools.com/info/longterm-job";
const GATEWAY_KEY = "<GATEWAY_KEY>";
const xApiKey = "<PERSONAL_KEY>";
const sessionId = "<SESSION_ID>";
const channelId = "UC…";
// Start one job. Start the next video only after this one is FINISHED or FAILED.
const job = await post({
xApiKey, requestType: "startTranslationJob", sessionId, channelId,
videoId: "dQw4w9WgXcQ", languages: ["es", "de", "fr"], capturesIncluded: true,
});
// Check every 5 seconds until the job is done.
let status;
do {
await new Promise((resolve) => setTimeout(resolve, 5000));
status = await post({ xApiKey, requestType: "getJobById", jobId: job.jobId });
} while (status && status.status !== "FINISHED" && status.status !== "FAILED");
console.log(status.status, status.response ?? status.reason);
async function post(body) {
const res = await fetch(API, {
method: "POST",
headers: { "Content-Type": "application/json", "x-api-key": GATEWAY_KEY },
body: JSON.stringify(body),
});
if (!res.ok) throw new Error((await res.json()).message);
return res.json();
}
Languages and Codes
- Send the codes in
languagesexactly as written below. They follow YouTube's codes, so Hebrew isiw, Latin American Spanish ises-419, and Cantonese isyue. - Channel means the code can also be used to translate a channel (a request without
videoId). Other codes are skipped for channels. The channel list also acceptsen-UK,filandnb.
| Code | Language | Channel |
|---|---|---|
az | Azerbaijani | Yes |
sq | Albanian | Yes |
en | English | Yes |
en-GB | English (UK) | |
en-IN | English (India) | Yes |
en-IE | English (Ireland) | |
en-CA | English (Canada) | |
en-US | English (United States) | |
en-AU | English (Australia) | |
ar | Arabic | Yes |
hy | Armenian | Yes |
eu | Basque | Yes |
be | Belarusian | Yes |
bn | Bengali | Yes |
my | Burmese | Yes |
bg | Bulgarian | Yes |
bs | Bosnian | Yes |
cy | Welsh | |
hu | Hungarian | Yes |
vi | Vietnamese | Yes |
haw | Hawaiian | |
ht | Haitian Creole | |
gl | Galician | Yes |
el | Greek | Yes |
ka | Georgian | Yes |
gu | Gujarati | Yes |
gd | Scottish Gaelic | |
da | Danish | Yes |
zu | Zulu | Yes |
iw | Hebrew | Yes |
yi | Yiddish | |
id | Indonesian | Yes |
ga | Irish | |
is | Icelandic | Yes |
es | Spanish | Yes |
es-ES | Spanish (Spain) | |
es-419 | Spanish (Latin America) | |
es-MX | Spanish (Mexico) | Yes |
es-US | Spanish (United States) | Yes |
it | Italian | Yes |
kk | Kazakh | Yes |
kn | Kannada | Yes |
yue | Cantonese | |
ca | Catalan | Yes |
ky | Kyrgyz | Yes |
zh | Chinese | Yes |
zh-TW | Chinese (Taiwan) | |
zh-CN | Chinese (China) | |
zh-Hans | Chinese (Simplified) | |
zh-HK | Chinese (Hong Kong) | Yes |
zh-SG | Chinese (Singapore) | |
ko | Korean | Yes |
co | Corsican | |
ku | Kurdish | |
km | Khmer | Yes |
lo | Lao | Yes |
la | Latin | |
lv | Latvian | Yes |
lt | Lithuanian | Yes |
lb | Luxembourgish | |
mk | Macedonian | Yes |
ms | Malay | Yes |
mn | Mongolian | Yes |
de | German | Yes |
de-AT | German (Austria) | |
de-DE | German (Germany) | |
de-CH | German (Switzerland) | |
ne | Nepali | Yes |
nl | Dutch | Yes |
nl-BE | Dutch (Belgium) | |
nl-NL | Dutch (Netherlands) | |
no | Norwegian | |
pa | Punjabi | Yes |
fa | Persian | Yes |
fa-AF | Persian (Afghanistan) | |
fa-IR | Persian (Iran) | |
pl | Polish | Yes |
pt | Portuguese | Yes |
pt-BR | Portuguese (Brazil) | Yes |
pt-PT | Portuguese (Portugal) | |
ro | Romanian | Yes |
ru | Russian | Yes |
sa | Sanskrit | |
sm | Samoan | |
sr | Serbian | Yes |
sk | Slovak | Yes |
sl | Slovenian | Yes |
so | Somali | |
tl | Tagalog (Filipino) | |
tg | Tajik | |
th | Thai | Yes |
ta | Tamil | Yes |
te | Telugu | Yes |
tr | Turkish | Yes |
uz | Uzbek | Yes |
uk | Ukrainian | Yes |
ur | Urdu | Yes |
fi | Finnish | Yes |
fr | French | Yes |
fr-BE | French (Belgium) | |
fr-CA | French (Canada) | Yes |
fr-FR | French (France) | |
fr-CH | French (Switzerland) | |
hi | Hindi | Yes |
hr | Croatian | Yes |
cs | Czech | Yes |
sv | Swedish | Yes |
eo | Esperanto | |
et | Estonian | Yes |
ja | Japanese | Yes |
jv | Javanese | |
af | Afrikaans | Yes |
ak | Akan | |
am | Amharic | Yes |
as | Assamese | Yes |
ay | Aymara | |
bm | Bambara | |
gn | Guarani | |
ha | Hausa | |
ig | Igbo | |
ln | Lingala | |
lg | Ganda | |
mg | Malagasy | |
ml | Malayalam | Yes |
mt | Maltese | |
mi | Maori | |
mr | Marathi | Yes |
or | Odia | Yes |
om | Oromo | |
ps | Pashto | |
st | South Sotho | |
sn | Shona | |
sd | Sindhi | |
si | Sinhala | Yes |
su | Sundanese | |
sw | Swahili | Yes |
tt | Tatar | |
ti | Tigrinya | |
ts | Tsonga | |
tk | Turkmen | |
ug | Uyghur | |
xh | Xhosa | |
yo | Yoruba |







