Developer API, CLI & MCP
Translate JSON, YAML, .strings, .po, ARB, Android XML, CSV, XLIFF 1.2, Java .properties, .NET RESX and Mozilla Fluent (.ftl) into 46 languages, with verify-meaning QA on every string — from the REST API, the CLI, your CI/CD pipeline, or your AI editor.
Terminal & CI. Incremental & reproducible — only new/changed keys.
pip install kaeris
Every translation — CLI, MCP, Action or raw API — runs through the same verify-meaning QA pass: each string is back-translated to catch meaning drift before it ships.
Agentic localization in CI
GitHub ActionPush a new string to locales/en.json. KAERIS translates just the new keys and opens a pull request with the diff — you review and merge like any other change. Zero-touch, incremental, with an i18n-firewall check gating merges on missing or placeholder-broken translations.
kaeris.lock — not a full re-translate every run.kaeris check --ci as a required status check — blocks merges with missing or broken translations.on: { push: { branches: [main], paths: ["locales/en.json"] } } jobs: translate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: RaiGanja/kaeris-action@v1 id: kaeris with: { source: locales/en.json, languages: es,fr,de,ja, only-new: "true" } - if: steps.kaeris.outputs.changed == 'true' uses: peter-evans/create-pull-request@v6 with: { branch: kaeris/i18n-updates, title: "i18n: new translations" }
Ready-to-copy workflow in the repo: .github/workflows/translate.example.yml — pair with i18n-check.example.yml as a branch-protection required check.
Reproducible by design
deterministicRun it again, get the same result. kaeris.lock records a hash of every source string, your settings and the model that produced them, so unchanged strings are never re-translated — the diff only ever contains what you actually changed. No surprise churn, no noisy PRs.
Get your free API key
Free API keys unlock 50,000 characters per file (vs 10,000 anonymous), no account required. Paid keys raise this: Pro 200k, Scale 500k, Team/API 1M, Lifetime 1M (BYOK) — see pricing.
Your API key — copy it now, it won't be shown again:
Pass as X-API-Key header in every request.
Quick start
Upload file → get job_id
# POST /api/translate curl -X POST https://kaeris.dev/api/translate \ -H "X-API-Key: kaeris_your_key_here" \ -F "[email protected]" \ -F "languages=ru,de,fr,es,zh,ja" # Response: { "job_id": "3f8a2c1d-..." }
Poll until done
# GET /api/status/{job_id} curl https://kaeris.dev/api/status/3f8a2c1d-... # Response when done: { "status": "done", "progress": 6, "total": 6, "error": "" }
Download ZIP
# GET /api/download/{job_id} curl -O https://kaeris.dev/api/download/3f8a2c1d-... # Saves translations.zip with ru.json, de.json, fr.json ...
Python example
import requests, time API_KEY = "kaeris_your_key_here" HEADERS = {"X-API-Key": API_KEY} # 1. Upload with open("en.json", "rb") as f: r = requests.post( "https://kaeris.dev/api/translate", headers=HEADERS, files={"file": f}, data={"languages": "ru,de,fr,es,zh,ja"}, ) job_id = r.json()["job_id"] # 2. Poll while True: status = requests.get(f"https://kaeris.dev/api/status/{job_id}").json() if status["status"] == "done": break time.sleep(2) # 3. Download zip_bytes = requests.get(f"https://kaeris.dev/api/download/{job_id}").content open("translations.zip", "wb").write(zip_bytes)
API Reference
Start a translation job. Returns job_id.
X-API-KeyHeader — optional. Raises limit to 50k chars (Pro: 200k; Team/API 1M).filemultipart — JSON file to translatelanguagesform field — comma-separated codes: ru,de,frPoll job progress. Status: pending | running | done | error.
progressbatches completed so fartotaltotal batchesDownload ZIP with ru.json, de.json etc. Available for 1 hour after completion.
Generate a new API key. No auth required.
Supported languages
en Englishru Russianuk Ukrainiande Germanfr Frenches Spanishpt Portugueseit Italianzh Chineseja Japaneseko Koreanar Arabicpl Polishnl Dutchtr Turkishhi Hindiid Indonesianvi Vietnameseth Thaims Malaybn Bengalifa Persianhe Hebrewsv Swedishcs Czechro Romanianhu Hungarianel Greekda Danishfi Finnishno Norwegiansk Slovakhr Croatianbg Bulgariansr Serbianlt Lithuanianlv Latvianet Estoniansl Slovenianca Catalantl Filipinosw Swahilizh-Hant Traditional Chinesees-419 Latin Am. Spanishpt-PT European Portuguesefr-CA Canadian French