JSON DeepL exposes the same HTTP endpoints its own web tool uses internally to talk to DeepL. On jsondeepl.com they're restricted to trusted callers — same-origin requests made from the jsondeepl.com frontend itself, not from other websites or scripts — to keep hosting costs predictable for a free, unauthenticated tool.
If you self-host your own copy of the project, that same origin restriction applies relative to your domain instead — so these endpoints become a real API for your own frontend to use, no configuration required. To call them directly (from a script, a build pipeline, another service — anything that isn't a browser page load from your own site), set a NUXT_APP_API_KEY env var on your deployment and send it back as the x-app-api-key header on each request.
curl https://your-domain.example/api/translate-text \
-H "x-app-api-key: $NUXT_APP_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "token": "your-deepl-key", "src_locale": "en", "to_locale": ["de"], "formality": "prefer_less", "text": "Hello world" }'
Nothing else changes either way: you still bring your own DeepL API key per request, and nothing is stored on the server.
POST /api/translateen *case insensitive["de", "fr", "es"] *case insensitivetype JsonFile = {
dir_name: string // subdirectory to nest this file's output under, or '' for none
prefix_name: string // filename prefix, e.g. 'app' -> app.de.json, or '' for none
json: string // the JSON content to translate, as a string
}
prefer_less: Translations will be casual tone where applicable.prefer_more: Translations will be more formal where applicable.json_files × to_locale combination.type TranslatedFile = {
dir_name: string
filename: string // e.g. 'app.de.json'
content: string // the translated JSON, stringified
}
On failure, the response is a standard HTTP error with a JSON body containing statusCode and statusMessage.
| Status | Meaning |
|---|---|
400 | One of the json_files entries isn't valid JSON, or the request body failed validation. |
401 | The DeepL API key is invalid. |
402 | The DeepL account has run out of translation quota. |
403 | The request wasn't recognized as a trusted caller — see the note above. |
502 | DeepL couldn't be reached, or translation failed for another reason. |
POST /api/translate-text// e.g. { "de": "Hallo Welt", "fr": "Bonjour le monde" }
Same shape and status codes as /api/translate above.