GuidesTRANSLATION APIS
Free translation APIs tested from the browser
We tested 8 translation APIs from a browser on 26 October 2026: 6 send CORS headers and work with fetch(), DeepL blocks browser calls, and the public Lingva instances failed. MyMemory is the keyless pick: one GET request, 5,000 characters a day, or 50,000 with an email address. Google Cloud Translation gives 500,000 free characters a month and works from the browser with a website-restricted key.
Every translation API we tested
We ran each API on 26 October 2026 with curl and an Origin: https://example.com header from a German datacenter IP, a US residential IP and through https://proxy.cors.dev/, then in Chromium 147.0.7727.15 from http://127.0.0.1:8001. Four need no key: MyMemory, Apertium, Lingva and Google's unofficial endpoint. More browser-ready endpoints are in our list of 70 free public APIs.
| API | Key | Browser CORS | Free limit | Notes |
|---|---|---|---|---|
| MyMemory | None (email optional) | Yes, ACAO * | 5,000 chars/day; 50,000 with an email | GET, up to 500 bytes per request |
| LibreTranslate (libretranslate.com) | Paid key | Yes, ACAO * | No free tier; from $29/month | Free to self-host |
| DeepL API | Free key | No, blocked at preflight | Developer plan: 1,000,000 characters once | API Free (500,000/month) closed to new signups |
| Google Cloud Translation Basic (v2) | Website-restricted key | Yes, echoes Origin | 500,000 chars/month, then $20 per million | $10 monthly credit shared with Advanced |
| Microsoft Translator | Free key (F0 tier) | Yes, ACAO * | 2,000,000 chars/month | Use 10-minute tokens from your backend |
| Apertium | None | Yes, ACAO * | No quota published | 133 language pairs, rule-based |
| Lingva Translate | None | Varies by instance | Depends on the instance | Unofficial Google front end; instances failed our test |
| Google translate_a/single (gtx) | None | Yes in Chromium | Undocumented | 429 to curl from 3 networks; can break any time |
MyMemory: free GET requests with a daily quota
MyMemory (https://api.mymemory.translated.net/get?q=...&langpair=en|de) takes one GET request, needs no key and sends Access-Control-Allow-Origin: *. "Where is the train station?" with langpair=en|de came back as "Wo ist der Bahnhof?".
Anonymous use is limited to 5,000 characters per day. Put a valid email address in the de parameter for 50,000 characters per day; CAT tool makers can ask to be whitelisted for 150,000. MyMemory counts the size of each request, not the number of requests, and the q parameter is limited to 500 bytes.
Call it directly, not through a shared CORS proxy. Through https://proxy.cors.dev/ MyMemory answered 429, because every proxy user shares the same quota, while direct calls returned 200.
const params = new URLSearchParams({ q: 'Where is the train station?', langpair: 'en|de' });
// A contact email raises the free quota from 5,000 to 50,000 characters a day
params.set('de', 'you@example.com');
const response = await fetch(`https://api.mymemory.translated.net/get?${params}`);
const body = await response.json().catch(() => null);
if (!response.ok || Number(body?.responseStatus) !== 200) {
throw new Error(`MyMemory failed: ${body?.responseDetails || response.status}`);
}
console.log(body.responseData.translatedText);Google Cloud Translation with a website-restricted key
Google Cloud Translation Basic (https://translation.googleapis.com/language/translate/v2) includes the first 500,000 characters per month free, applied as a $10 monthly credit shared with the Advanced edition, then charges $20 per 1,000,000 characters. It echoes your Origin on GET and POST and answers preflight requests, so fetch() works directly.
In the Google Cloud console, restrict the key to your website (HTTP referrers) and to the Cloud Translation API. A Referer header can be faked outside a browser, so the restriction stops other websites from using your key, not a script that copies it from your bundle. You don't need a proxy here, and the cors.dev free tier refuses URLs with key= anyway (HTTP 400, X-Cors-Error: credential_in_url).
// Restrict this key to your website and to the Cloud Translation API in the Google Cloud console
const apiKey = 'YOUR_WEBSITE_RESTRICTED_KEY';
const params = new URLSearchParams({
key: apiKey,
q: 'Where is the train station?',
target: 'de',
format: 'text',
});
const response = await fetch(`https://translation.googleapis.com/language/translate/v2?${params}`);
const body = await response.json().catch(() => null);
if (!response.ok) {
throw new Error(`Google Translate failed: ${body?.error?.message ?? response.status}`);
}
const [{ translatedText, detectedSourceLanguage }] = body.data.translations;
console.log(detectedSourceLanguage, '->', translatedText);DeepL needs a backend
DeepL (https://api-free.deepl.com/v2/translate) sends no CORS headers. Its preflight answered 204 without Access-Control-Allow-Origin, and Chromium 147 reported: Access to fetch at 'https://api-free.deepl.com/v2/translate' from origin 'http://127.0.0.1:8001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If the same call works in your terminal, here is why curl and Postman behave differently.
That is deliberate. DeepL's docs say the API does not allow calls from browser-based apps, tell you never to reveal your key in public code, and point you to your own backend. Keep the DeepL key on your server behind a small API proxy for your frontend, never in the browser or a public proxy.
The free tier changed too. Existing DeepL API Free accounts still get 500,000 characters per month, but the plan can no longer be purchased. New users get the Developer plan: a one-time 1,000,000 characters that does not reset. Each request can be up to 128 KiB.
Microsoft Translator and LibreTranslate
Microsoft Translator (https://api.cognitive.microsofttranslator.com) has a free F0 tier of 2 million characters per month, standard translation and custom training combined, with up to 50,000 characters per request. It sends Access-Control-Allow-Origin: *, its preflight allows the key header, and /languages needs no key. Authenticate with an Ocp-Apim-Subscription-Key header or a Bearer token from https://api.cognitive.microsoft.com/sts/v1.0/issueToken, valid for 10 minutes. Keep the subscription key on your backend and hand the browser short-lived tokens.
LibreTranslate is open source and free to self-host, and it sends Access-Control-Allow-Origin: * with a preflight that allows Authorization and Content-Type. The hosted libretranslate.com is paid only: POST /translate without a key returned 400 {"error":"Visit https://portal.libretranslate.com to get an API key"}. Plans cost $29 per month (bursts up to 80 calls per minute, about 20 sustained, 2,000 characters per call) or $58 for 200 calls per minute, with no free trial and a 7-day money-back guarantee. For a free browser setup, run your own instance and call it directly; keep a paid hosted key on your backend.
Apertium, Lingva and unofficial Google endpoints
- Apertium (
https://apertium.org/apy/translate?q=...&langpair=eng|spa): free, open-source, rule-based translation with no key andAccess-Control-Allow-Origin: *./listPairsreturned 133 language pairs, and "Hello world" ineng|spareturned "Hola Mundo". No quota is published. - Lingva Translate: an open-source front end for Google Translate built on a Google Translate scraper, with
GET /api/v1/:source/:target/:queryon each instance. None of the public instances we tried worked:lingva.mlreturned 403 to our datacenter IP and untranslated text through the proxy,lingva.lunar.icuandtranslate.plausibility.cloudreturned 500, andlingva.garudalinux.orgreturned 403. - Google's translate_a endpoint (
translate_a/single?client=gtx): undocumented, no terms, no SLA.curlfrom our datacenter IP, a residential IP and the proxy got 429 "Sorry" pages, while Chromium 147 got 200 with CORS headers on both networks. Google can change or block it at any time, so keep it out of production.
Good questions.
Is there a free translation API without an API key?
Yes. MyMemory and Apertium both work from the browser without a key and send Access-Control-Allow-Origin: *. MyMemory allows 5,000 characters per day anonymously, or 50,000 with your email in the de parameter.
Can I call the DeepL API from JavaScript in the browser?
No. DeepL sends no Access-Control-Allow-Origin header on its preflight, and its docs say to call the API from your backend so the key stays private.
Is the DeepL API Free plan still available?
Not for new users. Existing API Free accounts keep 500,000 characters per month; new users get the Developer plan with a one-time 1,000,000 characters that does not reset.
Is the Google Translate API free?
Cloud Translation Basic includes 500,000 characters per month through a $10 monthly credit, then costs $20 per 1,000,000 characters. It sends CORS headers, so you can call it from the browser with a website-restricted key.
Is LibreTranslate free?
Self-hosting is free, and your own instance sends CORS headers for browser calls. The hosted libretranslate.com API needs a paid key, from $29 per month.
Can I send translation requests through a CORS proxy?
You rarely need one: MyMemory, Google, Microsoft, LibreTranslate and Apertium all send CORS headers. MyMemory through https://proxy.cors.dev/ returned 429 because proxy users share one quota, and private keys for DeepL, Microsoft or LibreTranslate belong on your backend, not in a public proxy.