CLI Commands#

Every data command accepts --json for parseable output on stdout. The authoritative reference for the version you have installed is the CLI itself:

multilocale schema                 # the whole command tree as JSON
multilocale schema projects create # one command's arguments and flags

signup#

Create an account and log in, with no browser.

multilocale signup [options]

Options#

Flag Description
--email <email> Email address for the new account
--password <password> Password (omit to have a strong one generated)
--first-name <firstName> First name (default: derived from the email)
--last-name <lastName> Last name (default: derived from the email)
--json Print the result as JSON

Examples#

multilocale signup --email you@example.com --json

The generated password is printed exactly once; a password you passed in is never echoed back. The session is stored, so the next command is already authenticated. Signup also creates a first project named after the local part of the email, with defaultLocale: "en", locales: ["en"] and paths: ["translations/%lang%.json"].

Without --email the command prompts on a TTY and fails immediately without one. An address that already has an account exits 1 with this email already has an account — use login instead.


login#

Authenticate an account that already exists. There is no email/password prompt: the two ways in are a browser session and an API key secret.

multilocale login [options]

Options#

Flag Description
--browser Log in through the browser (opens app.multilocale.com)
--with-key Log in with an API key secret, entered at a masked prompt

With no flags on a TTY the command asks which of the two to use. The API key secret is never accepted as a command-line argument — prompt or environment variable only. A key the API rejects is not stored.

Without a TTY, login does not open a browser: it prints instructions on stderr and exits 1. Export the key instead:

export MULTILOCALE_API_KEY=<key secret>

Precedence is stored browser session → stored API key secret → MULTILOCALE_API_KEY.


logout#

Clear the stored session and any stored API key.

multilocale logout

MULTILOCALE_API_KEY is not ours to unset, so if it is exported the CLI stays authenticated through it after logout — and says so.


projects#

Manage projects.

multilocale projects list                    # names and ids
multilocale projects get [projectIdOrName]   # raw JSON; all projects when omitted
multilocale projects read <projectIdOrName>  # formatted single-project view
multilocale projects create <name> [options]
multilocale projects update <projectIdOrName> [options]

create options#

Flag Description
--locales <locales> Comma-separated locale list (default: just the default locale)
--default-locale <locale> Default locale (default: en)
--paths <patterns...> Where the translation files live, %lang% standing in for the locale
--json Print the result as JSON

update options#

Flag Description
--name <name> Rename the project
--locales <locales> Locales to add; locales already on the project are kept
--remove-locales <locales> Locales to remove (the default locale cannot be removed)
--set-locales <locales> Replace the locale list outright — destructive
--default-locale <locale> Default locale; always kept in the locale list
--paths <patterns...> Where the translation files live
--context <context> Project context handed to the machine translator
--json Print the result as JSON

Every list-shaped option accepts the same three spellings: --paths a,b, --paths a b, and --paths a --paths b.

Examples#

multilocale projects create my-app --locales en,es,fr --default-locale en

# Tell the CLI where this project's translation files live
multilocale projects update my-app --paths "translations/%lang%.json"
multilocale projects update my-app --paths "messages/%lang%.json,src/i18n/%lang%.json"

# Add two locales, keeping the ones already there
multilocale projects update my-app --locales ja,ko

projects update is the only way to set paths, which download, import and unused read off the project — see Configuration. It reads the project and merges your changes into it, so fields you did not name are preserved.

On the wire locales is a complete replacement list, which is why the CLI does not expose it that way: --locales adds, --remove-locales removes, and --set-locales is the explicit destructive replace. Removing the default locale is refused; pass --default-locale <other> in the same command first.

Project names are unique per organization, so a project id and a project name are interchangeable everywhere.


download#

Download translation files from Multilocale to your local project.

multilocale download [options]

Options#

Flag Description
--project [project] Project ID or name
--format [format] Output format: json, esm, js, cjs, swift
--extension [extension] File extension for dictionary files
--header [header] Header text prepended to each file
--post-script [post-script] Shell command to run after download
--json Print the result as JSON

Examples#

# Download as JSON files
multilocale download --project my-app --format json

# Download as ES modules
multilocale download --project my-app --format esm --extension js

# Reshape the output for your i18n runtime afterwards
multilocale download --post-script "node scripts/normalizeMessages.mjs"

Files are written to the project's paths, which use %lang% as the language placeholder, e.g. translations/%lang%.json. With no paths configured anywhere the CLI falls back to translations/<locale>.<extension> — or <locale>.lproj/Localizable.strings for the swift format.

For Android projects, the CLI detects AndroidManifest.xml and writes res/values-<locale>/strings.xml with Android's escaping rules applied.


import#

Import local translation files into Multilocale.

multilocale import [options]

Options#

Flag Description
--project [project] Project ID or name
--no-flatten Refuse nested dictionaries instead of flattening them
--json Print the result as JSON

Examples#

multilocale import --project my-app

The CLI detects whether your project is an Android or JavaScript project:

  • Android: Reads strings.xml files from res/values*/ directories
  • JavaScript: Reads JSON files based on the project's paths configuration

Missing translations for any language are auto-translated using the default locale as the source.

Import once per codebase

Re-importing creates duplicate rows rather than merging. import is the onboarding step for a codebase that already has translation files — run it once, and use add, update and download from then on. If you have imported twice already, multilocale duplicates lists the keys that now share a value.

A phrase is a flat key/value pair, so a nested dictionary — {"checkout": {"failed": "…"}} — is flattened to dot paths (checkout.failed) before upload. Literal dots and backslashes in a key are escaped. Values that cannot become a phrase (arrays, empty objects, null) are reported and skipped rather than invented. Pass --no-flatten to make a nested file an error instead.


add#

Add a new phrase and auto-translate it to all project locales.

multilocale add <key> [value] [options]

Arguments#

Argument Description
key The translation key
value The value in the default language. If omitted, uses the key as the value.

Options#

Flag Description
--project [project] Project ID or name
-m, --model <model> Translation model: gpt-5.6-luna (default), gpt-5-mini, gemini-3.5-flash, or claude-haiku-4-5
-c, --context <context> Context hint passed to the translation model
--json Print the result as JSON

Examples#

# Add with explicit value
multilocale add welcome_message "Welcome to our app" --project my-app

# Add using key as value
multilocale add "Welcome to our app" --project my-app

# Disambiguate a short string before it is translated 96 times
multilocale add "Max guests" \
  --context "Hotel software; the maximum number of guests a room sleeps, not software users"

The phrase is created in the project's default locale, then auto-translated to all other locales. add refuses a key that already exists in the project, and always creates a fresh phrase — to attach an existing phrase from another project, use share.


update#

Set the exact value of one key in one language.

multilocale update <key> <value> [options]

Options#

Flag Description
-l, --language <language> Language code (default: the project's default locale)
--project [project] Project ID or name
--json Print the result as JSON
multilocale update welcome_message "Bienvenue" -l fr

The machine-translated flags are cleared. A phrase shared with other projects changes for all of them — check multilocale phrases get <key> first.


delete#

Delete every locale row of a key.

multilocale delete <key> [--project my-app]

Shared rows are removed outright rather than detached from the current project, so this can affect other projects. Check multilocale phrases get <key> first.


share#

Attach one or more projects to every locale row of an existing phrase.

multilocale share <key> <targets...> [--project source-project]
multilocale share welcome_message other-project

--project selects the source project. The targets receive only the locales the source phrase already has, and future edits to the phrase affect all of them.


phrases#

Query phrases.

multilocale phrases list [options]        # grouped by language
multilocale phrases get [key] [options]   # raw JSON rows

Options#

Flag Description
--project [project] Project ID or name
-l, --language [language] Filter by language
-k, --key [key] Filter by key
--languages list only: print just the language list
-n, --limit [limit] get only: limit the number of rows
--json Print the result as JSON

localize#

Add one or more locales to a project and translate all existing phrases into them.

multilocale localize <locales> [options]

Arguments#

Argument Description
locales Comma-separated locale codes, or all to add all supported languages

Options#

Flag Description
--project [project] Project ID or name
-m, --model <model> Translation model: gpt-5.6-luna (default), gpt-5-mini, gemini-3.5-flash, or claude-haiku-4-5
--json Print the result as JSON

Examples#

# Add Spanish and French
multilocale localize es,fr --project my-app

# Add all supported languages
multilocale localize all --project my-app --model claude-haiku-4-5

Locales that already exist in the project are reconciled so interrupted or partial translation runs can be completed safely. For JavaScript projects, the CLI reads existing translation files or fetches the phrases from Multilocale and translates only the missing locale rows. Shared phrases remain shared with all of their existing projects.


unused#

Find translation keys that are not referenced in any source file.

multilocale unused [options]

Options#

Flag Description
--project [project] Project ID or name
--json Print the result as JSON

Examples#

multilocale unused --project my-app

The CLI scans all .js, .jsx, .ts, .tsx, .cjs, and .mjs files in your project for references to each translation key. Keys that are not found in any source file are reported. Keys assembled dynamically at runtime look unused, so treat the output as candidates rather than a delete list. Android projects are not supported yet.


duplicates#

Find phrase keys that have duplicate values in the default language.

multilocale duplicates [options]

Options#

Flag Description
--project [project] Project ID or name
--json Print the result as JSON

Examples#

multilocale duplicates --project my-app

This helps identify phrases that could be consolidated — including the ones a second import created. For each duplicate value, the command lists all keys sharing that value and notes if any are shared with other projects.


skills#

Print the agent guides bundled with this version of the CLI.

multilocale skills list              # names and descriptions
multilocale skills get multilocale   # print one SKILL.md to stdout

schema#

Print the command tree as JSON, generated from the CLI as it actually runs.

multilocale schema
multilocale schema projects create