Skip to main content
There are two ways to import translations: the dashboard (CSV or JSON, any size, with a staging step) and the public API (JSON only, for scripts and CI). Both apply changes as a background job, so large imports don’t block the request.

Dashboard Import

Upload a file from the dashboard’s bulk import screen:
  • CSV (key / value columns)
  • JSON (key-value structure, matching the export shape)
Uploaded data is staged first, then applied as a background job.

API / CLI Import

POST /api/v1/push (scope translations:write) takes a JSON request body whose content field holds the translation file as a string — the easiest way to call it is the CLI:
--dry-run parses and validates the file, returning a row count and a create/update preview, without touching the database. Nested JSON objects flatten into dot-separated keys ({"auth":{"title":"Sign in"}} imports as auth.title); a null value imports as the literal string "null" and arrays flatten into index-suffixed keys (key.0, key.1, …) rather than being rejected — avoid null/array values in files you push.
  1. Prepare clean key and locale columns
  2. Validate file encoding and structure
  3. Import in merge mode first (or --dry-run via the API/CLI)
  4. Verify sample keys before a full rollout

Import Modes

  • Merge: add/update entries without removing existing records
  • Replace: intentionally overwrite the existing dataset

Common Failures

  • Invalid locale headers
  • Duplicate keys with conflicting values
  • Unexpected encoding issues (non UTF-8)
  • Payload over the size cap (12 MB / 50,000 rows for the API/CLI path)

Next Steps