Translato CLI

The Translato CLI lets you push and pull translation keys between your local i18n files and the Translato TMS directly from the command line or CI/CD pipelines.

Installation

# Global install
npm install -g translato-cli

# Or run directly with npx
npx translato-cli --help

# Or add to your project
npm install --save-dev translato-cli

Quick Start

# 1. Initialize config (creates .translato.yml with your credentials)
translato init

# 2. Push source language keys to the TMS
translato push

# 3. Pull translations back to local files
translato pull

# 4. Or do both in one step
translato sync

# 5. Check translation progress
translato status

Authentication

The CLI authenticates via API keys. Generate one in your Translato dashboard:

  1. Go to SettingsAPI Keys
  2. Click "Generate New Key"
  3. Copy the key (starts with tlto_live_)

The recommended way to configure credentials is via translato login followed by translato init, which saves your API key to .env and creates a .translato.yml config file.

You can also pass credentials via environment variables or CLI flags (see Options Reference).

Commands

translato push

Upload translation keys from your local source language file to the TMS.

translato push

What it does:

  1. Checks for unpulled remote changes (blocks push if stale — run translato pull first, or --force to skip)
  2. Scans local files matching the glob pattern from your config
  3. Reads only the source language file (e.g. en.json)
  4. Extracts all keys (supports nested JSON → dot notation)
  5. Checks for orphan keys on remote (blocks if found — use --force to skip)
  6. Sends new keys and source-language values to the TMS

Output:

Pushing keys to Translato...

  📄 src/locales/en.json — 142 keys

  Total unique keys: 142

✅ Push complete:
   Parsed: 142
   Added:  8

New keys are added as terms, and source-language values are stored as translations. Existing keys are updated if the source text changed (tracked via SHA-256 hash in .translato.state).

translato pull

Download translations from the TMS to your local files.

translato pull

What it does:

  1. Fetches the list of languages in your project
  2. Downloads translations for every language (including source) in parallel
  3. Writes them to local files based on your config's file pattern
  4. Records a pull timestamp so push can detect stale state

Output:

Pulling translations from Translato...

  Languages: en, de, fr, es, ja

  ✅ de — 138 keys → src/locales/de.json
  ✅ fr — 125 keys → src/locales/fr.json
  ✅ es — 142 keys → src/locales/es.json
  ✅ ja — 98 keys → src/locales/ja.json

✅ Pull complete.

Files are written as nested JSON (dot-notation keys are expanded). Directories are created automatically. Use --lang de,fr to pull only specific languages, or --exclude-lang en to skip one.

Note: If any language fails during pull, the pull timestamp is not updated. This ensures push will still detect stale state.

translato sync

Two-way sync — pushes keys first, then pulls translations.

translato sync

Equivalent to running push followed by pull, but the pull-before-push guard is automatically skipped (since pull runs immediately after). Orphan key detection remains active.

translato status

Show project status with translation progress.

translato status

Output:

📊 Translato Project Status

  Project:   My Web App
  ID:        abc123
  Terms:     142
  Created:   2026-01-15T10:30:00.000Z

  Languages:
    en     ████████████████████ 100%
    de     ████████████████░░░░ 82%
    fr     ██████████████░░░░░░ 71%
    es     ████████████████████ 100%
    ja     █████████████░░░░░░░ 65%

translato validate

Check translation files for issues without contacting the API.

translato validate

Checks for missing keys, extra keys, empty values, and placeholder mismatches.

translato diff

Compare local translation files with remote TMS translations.

translato diff
translato diff --json   # CI mode — exits non-zero when drift is detected

Shows keys only in local, keys only in remote, and value differences. In --json mode, the command exits with a non-zero code when differences exist, making it suitable for CI pipelines that gate on translation drift.

translato watch

Watch source files and auto-push on save.

translato watch

translato logout

Remove stored credentials (TRANSLATO_API_KEY, TRANSLATO_PROJECT) from .env. If the file becomes empty after removal, it is deleted.

translato logout

Configuration (.translato.yml)

Running translato init creates this file. All credentials and settings are stored here — no need to pass flags on every command.

project: my-app

paths:
  locales: ./src/locales
  source: en
  format: json

languages:
  - en
  - de
  - fr
  - es

namespaces:
  - name: auth
    file: auth.json
  - name: common
    file: common.json

hooks:
  pre-push: npm run lint:translations
  post-pull: npm run format:translations

Config Priority

CLI flags override environment variables, which override config file values:

--api-key flag  >  TRANSLATO_API_KEY env  >  api.token in .translato.yml

Options Reference

These flags can be passed to any command. Credential flags (--api-key, --project, --host) are saved to .env for future use:

OptionEnv VariableDefaultDescription
--api-key <key>TRANSLATO_API_KEYfrom .envAPI key — saved to .env
--project <id>TRANSLATO_PROJECTfrom .envProject ID — saved to .env
--host <url>TRANSLATO_HOSTAPI server URL (optional — only for self-hosted instances)
--files <glob>src/locales/*.jsonFile glob pattern
--format <fmt>jsonjson / yaml / po / properties
--out-dir <path>Output directory for pulled translations
--concurrency <n>5Max parallel language downloads (1–20)
--forceSkip orphan key warnings on push
--lang <codes>Only process these languages (comma-separated)
--exclude-lang <codes>Skip these languages (comma-separated)
--skip-existingSkip files that already exist locally (pull only)
--jsonOutput results as JSON (for CI pipelines)
--dry-runPreview changes without making API calls or writing files
--verboseShow detailed output including API requests

CI/CD Integration

In CI/CD, pass credentials via environment variables. The CLI reads them automatically.

GitHub Actions

name: Translation Sync
on:
  push:
    branches: [main]
    paths: ['src/locales/en.json']

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npx translato-cli push
        env:
          TRANSLATO_API_KEY: ${{ secrets.TRANSLATO_API_KEY }}
          TRANSLATO_PROJECT: ${{ secrets.TRANSLATO_PROJECT }}

Pull translations on a schedule:

name: Pull Translations
on:
  schedule:
    - cron: '0 6 * * 1'  # Every Monday at 6am

jobs:
  pull:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npx translato-cli pull
        env:
          TRANSLATO_API_KEY: ${{ secrets.TRANSLATO_API_KEY }}
          TRANSLATO_PROJECT: ${{ secrets.TRANSLATO_PROJECT }}
      - uses: peter-evans/create-pull-request@v6
        with:
          title: 'chore(i18n): update translations'
          body: 'Automated translation pull from Translato'
          branch: translato/auto-pull

GitLab CI

translation-sync:
  stage: deploy
  image: node:20-slim
  script:
    - npx translato-cli sync
  variables:
    TRANSLATO_API_KEY: $TRANSLATO_API_KEY
    TRANSLATO_PROJECT: $TRANSLATO_PROJECT
  only:
    changes:
      - src/locales/en.json

File Formats

FormatExtensionsNotes
JSON.jsonNested objects flattened to dot notation, unflattened on write
YAML.yml, .yamlFull YAML support via js-yaml
PO/Gettext.po, .potSupports msgid/msgstr, multiline, msgctxt, plural forms
Properties.propertieskey=value pairs with newline escaping

Troubleshooting

"Missing API key"

Make sure .translato.yml exists and has your credentials, or set the TRANSLATO_API_KEY environment variable.

"No files found matching"

Check that the glob pattern in your config matches your file structure:

ls src/locales/*.json

"HTTP 401"

Your API key may be invalid or expired. Generate a new one in the dashboard.

"HTTP 404"

Check that the project ID in your config is correct. Find it on your project's settings page.