Skip to content

CLI

Updated: September 16, 2026

azbox-cli downloads your project’s translations and writes them to files, so a build step can do it instead of a person. It is open source (GitHub) and has no dependencies.

What it does, and what it can’t

It reads. There is no push: keys are created in the dashboard or by importing a file from it, and the API does not write keywords. If you type azbox push, the CLI says so instead of pretending.

That still covers the case that matters in CI: fetch the current translations, write them to files, commit or bundle them.

Install

npm install --save-dev azbox-cli

Node 18 or newer. Or skip the install and run it once with npx azbox-cli.

Credentials

You need the project ID and an API key.

  1. In the dashboard, open Settings → API keys and create a key tied to the project. It can only read that project, and you can revoke it without touching anything else.
  2. Copy it when it is shown: it is stored hashed and cannot be displayed again.
export AZBOX_PROJECT_ID=your-project-id
export AZBOX_TOKEN=azb_live_…

The account API key shown in Settings also works, but it opens every project in the account and cannot be revoked. Prefer a project key.

The key is never read from azbox.json. That file gets committed, and a key in a repository is a leak: the CLI refuses to start if it finds one there.

Configuration

Everything can go on the command line, but a project usually wants an azbox.json in its root:

{
  "projectId": "your-project-id",
  "languages": ["EN", "ES"],
  "out": "locales/{language}.{ext}",
  "format": "json"
}

Flags win over environment variables, which win over the file.

Language codes are the project’s (EN-US, ES, PT-PT). From version 0.1.1 the case does not matter: -l es asks for ES and writes es.json.

Commands

azbox pull

Downloads and writes one file per language. It creates directories as needed and leaves a file alone when its content has not changed, so it is safe to run on every build.

azbox pull -l ES                                   # locales/ES.json
azbox pull -l es -f arb -o "l10n/app_{language}.{ext}"
azbox pull -l ES --since 2026-09-01                # only what changed since then
azbox pull -l ES --dry-run                         # say what it would write

azbox status

Same request, writes nothing. Reports how many keys are translated in each language and how many still have no text.

azbox qa

Checks the translations against the source language and exits with 1 if something is broken, so a bad translation stops a deploy instead of reaching users. Missing or invented placeholders, broken ICU plurals, mismatched HTML, text that will overflow. See the quality report.

azbox qa                         # summary, fails on errors
azbox qa --fail-on warning       # also fail on length and spacing warnings
azbox qa --json > qa.json        # the whole report, to keep as an artifact

Options

OptionMeaning
-p, --project <id>project ID, or AZBOX_PROJECT_ID
-t, --token <key>API key, or AZBOX_TOKEN
-l, --language <code>language; repeat it for several, or AZBOX_LANGUAGES=EN,ES
-o, --out <template>output path; {language} and {ext} are substituted
-f, --format <fmt>json or arb
--flatJSON with dotted keys instead of nested objects
--since <iso date>only keywords updated after that date
--dry-runreport, don’t write
--source <code>qa: language to compare against (default: the project’s first)
--fail-on <level>qa: error (default), warning or none
--json, --csvqa: print the full report instead of a summary

Formats

json nests dotted keys, which is what i18next expects: home.title becomes { "home": { "title": … } }. Use --flat to keep the dots. If two keys collide — home and home.title in the same project — nesting would destroy one of them, so the CLI writes flat and tells you.

arb is always flat, with @@locale set from the language, because Flutter’s generator expects keys at the top level.

In CI

- run: npx azbox-cli pull -l EN -l ES
  env:
    AZBOX_PROJECT_ID: ${{ vars.AZBOX_PROJECT_ID }}
    AZBOX_TOKEN: ${{ secrets.AZBOX_TOKEN }}

- name: Check the translations
  run: npx azbox-cli qa --fail-on error
  env:
    AZBOX_PROJECT_ID: ${{ vars.AZBOX_PROJECT_ID }}
    AZBOX_TOKEN: ${{ secrets.AZBOX_TOKEN }}

Exit codes: 0 fine, 1 the API failed for at least one language — or, for qa, there are issues at or above --fail-on — and 2 it was called wrong.

Worth knowing

  • A key with no translation is skipped, not written as an empty string. Writing empty strings would overwrite good translations with nothing.
  • Keys are sorted alphabetically, so a diff shows only what changed.
  • An empty language is not an error. The file is simply not written.
  • Placeholders come back exactly as stored. Interpolation is up to your i18n library.

Underneath it is one call to the REST API.

Call to action background

Start Global Growth Today

Upload your language files, get them translated, and keep every locale in sync as your product keeps changing.

Get Started - It's Free