Data
Import & Export
Upload existing translation files to get started quickly, or download your translations in the format your application needs — through the UI or the REST API.
Supported format
Mergua works with JSON files — the standard format used by Angular/Transloco and i18next. Both flat and nested key structures are supported and auto-detected.
Nested JSON
{
"common": {
"save": "Save",
"cancel": "Cancel"
}
}Flat JSON
{
"common.save": "Save",
"common.cancel": "Cancel"
}ARB (with descriptions)
Plain JSON carries only keys and values, so a download loses the context notes and max lengths your team maintains in the editor. Use ARB (Application Resource Bundle) when you want them to travel with the file. ARB is JSON with @key metadata entries, and Mergua supports it for both import and export — so notes survive a full round-trip.
ARB file
{
"@@locale": "fr",
"@@last_modified": "2026-08-14T09:30:00.000Z",
"common.save": "Enregistrer",
"@common.save": {
"description": "Primary button",
"x-maxLength": 12,
"source_text": "Save",
"type": "text"
}
}How it maps
@key.description→ the key's context note@key.x-maxLength→ the key's max length (ARB has no standard slot for this, so Mergua uses a custom attribute)@key.source_text→ the original this was translated from, written for every language except your source one. Bring it back on import and the preview names the keys whose original has changed since.@@last_modified→ when the exported values last changed. Taken from the data, not from the time of export, so pulling twice gives you the same file.- Attributes Mergua does not edit — Flutter's
placeholders,screenshot, anything else in your file — are kept as they are and written back out, up to 4 KB per key. - Imports are additive — a file without metadata never removes notes you already have.
Import: drop a .arb file into the import dialog. Export: pick ARB in the download dialog, use the editor's Export menu, or ask the API below for ?format=arb. For the files your app loads at runtime, stick to plain JSON — ARB is for round-tripping context notes.
Importing
Import keys (source file)
Upload your source language file (e.g. en.json) to import all keys into the project. New keys are added with empty translations for all target languages. Existing keys are preserved — no data is overwritten.
Mergua shows a preview of what will be added before committing.
Import translations
Upload a translated file (e.g. fr.json) for a specific language. Translations are merged into the project. If a key already has a value, you choose how to handle conflicts:
- Keep existing — existing translations stay, only empty keys are filled.
- Use uploaded — uploaded values overwrite existing translations.
Exporting
Download single locale
Download translations for a specific language as a .json file. The file is named by locale code (e.g. fr.json).
Download all locales
Download all translations as a .zip archive (UI only). The ZIP contains one JSON file per language, ready to drop into your project's i18n folder.
JSON format options
Choose between nested and flat JSON output. The format is configured per download or via the format query parameter on the API.
API access
Download translations programmatically with the REST API — no pipeline required. Handy for custom build scripts, a quick one-off pull, or wiring Mergua into another tool.
Authentication
Every request needs your project API key in the X-API-Key header. Create one under your project's API Keys settings.
Download a single locale
curl -H "X-API-Key: $MERGUA_API_KEY" \
"https://develop.backend.mergua.com/v1/$PROJECT_ID/translations/fr" Returns the locale as JSON. The resolved branch is echoed in the X-Mergua-Branch response header.
Download all locales
Returns a JSON object with one entry per locale (for a ZIP archive, use the UI):
curl -H "X-API-Key: $MERGUA_API_KEY" \
"https://develop.backend.mergua.com/v1/$PROJECT_ID/translations"Query parameters
| Parameter | Default | Description |
|---|---|---|
| format | nested | nested or flat JSON output, or arb for JSON with @key metadata. Anything else returns 400. |
| branch | main | Mergua branch to pull from |
# flat JSON from the develop branch
curl -H "X-API-Key: $MERGUA_API_KEY" \
"https://develop.backend.mergua.com/v1/$PROJECT_ID/translations/fr?format=flat&branch=develop"
# ARB — same values, plus descriptions and max lengths
curl -H "X-API-Key: $MERGUA_API_KEY" \
"https://develop.backend.mergua.com/v1/$PROJECT_ID/translations/fr?format=arb" ARB works on both download endpoints and on any branch. The response stays application/json — an ARB document is valid JSON, so existing parsers keep working.
Upload translations
Upload translations for a specific locale. The request body is a JSON object with translation keys and values (flat or nested).
curl -X PUT -H "X-API-Key: $MERGUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"auth.login.title": "Anmelden"}' \
"https://develop.backend.mergua.com/v1/$PROJECT_ID/translations/de"Conflict strategy
Control what happens when a translation already exists using the strategy query parameter:
| Strategy | Existing translation | Empty / Draft | New |
|---|---|---|---|
| overwrite | Replaced | Replaced | Created |
| skip | Kept | Kept | Created |
| fill | Kept | Replaced | Created |
Default is overwrite. Use fill to seed missing translations without overwriting work already done by your team.
# Only fill empty/draft translations
curl -X PUT -H "X-API-Key: $MERGUA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"auth.login.title": "Anmelden"}' \
"https://develop.backend.mergua.com/v1/$PROJECT_ID/translations/de?strategy=fill"Other endpoints
GET /v1/{projectId}/locales— list locales and the source localeGET /v1/{projectId}/progress— translation progress per locale, optionally for a branch via?branch=…GET /v1/{projectId}/branches?name=…— check whether a branch exists
Want this to run automatically on every push (and commit the files back)? Use the Pipeline Sync script instead — it wraps these endpoints with branch matching, key sync and merge handling.