Import/Export API
Comvi provides two ways to import and export translations: a multi-step web import flow (validate, review, commit) and a streamlined CLI-oriented flow. Both support JSON and i18next v4 formats.
Export translations
Section titled “Export translations”Export translations from a project, filtered by locale, namespace, and status.
Web export
Section titled “Web export”Export translations using a POST request with filtering options. Returns a structured JSON response.
POST /api/v1/projects/:projectId/keys/exportPath parameters
Section titled “Path parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
projectId | integer | Yes | Project ID |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
keyIds | integer[] | No | Export only specific key IDs |
localeCodes | string[] | No | Filter by locale codes (all locales if omitted) |
namespaces | string[] | No | Filter by namespace names (all namespaces if omitted) |
format | string | No | Output format: json or i18next-v4 (default: json) |
statuses | string[] | No | Filter by status: translated, not_reviewed, not_translated |
includeEmpty | boolean | No | Include keys with no translation value (default: false) |
structure | string | No | Key structure: flat or nested (default: flat) |
style | string | No | JSON formatting: pretty or minified (default: pretty) |
Example request
Section titled “Example request”curl -X POST \ -H "X-API-Key: tlk_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "localeCodes": ["en", "uk"], "namespaces": ["default"], "format": "json", "statuses": ["translated"], "structure": "flat", "style": "pretty" }' \ https://api.comvi.io/api/v1/projects/1/keys/exportExample response
Section titled “Example response”{ "data": { "default": { "en": { "welcome.message": "Welcome to our app!", "welcome.subtitle": "Get started in seconds" }, "uk": { "welcome.message": "Ласкаво просимо!", "welcome.subtitle": "Почніть за секунди" } } }}CLI export
Section titled “CLI export”A simplified export endpoint designed for the Comvi CLI. Returns all translations grouped by namespace and locale.
GET /api/v1/projects/:projectId/exportQuery parameters
Section titled “Query parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
locales | string | No | Comma-separated locale codes |
namespaces | string | No | Comma-separated namespace names |
statuses | string | No | Comma-separated statuses |
includeEmpty | boolean | No | Include keys with no translation value |
Example request
Section titled “Example request”curl -X GET \ -H "X-API-Key: tlk_your_api_key" \ "https://api.comvi.io/api/v1/projects/1/export?locales=en,uk&namespaces=default"Example response
Section titled “Example response”{ "locales": ["en", "uk"], "namespaces": { "default": { "en": { "welcome.message": "Welcome to our app!", "welcome.subtitle": "Get started in seconds" }, "uk": { "welcome.message": "Ласкаво просимо!", "welcome.subtitle": "Почніть за секунди" } } }}Error codes (export)
Section titled “Error codes (export)”| Status | Error | Description |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid authentication |
403 | FORBIDDEN | No permission to export from this project |
Import translations (web flow)
Section titled “Import translations (web flow)”The web import is a three-step process: validate, optionally re-validate after user edits, then commit.
Step 1: Validate import
Section titled “Step 1: Validate import”Upload files for validation. Comvi detects file format, locale, namespace, and identifies any conflicts with existing translations.
POST /api/v1/projects/:projectId/keys/import/validatePath parameters
Section titled “Path parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
projectId | integer | Yes | Project ID |
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
files | object[] | Yes | Array of file objects to validate |
files[].filename | string | Yes | Original filename (used for format detection) |
files[].content | string | Yes | File content as string |
files[].size | integer | Yes | File size in bytes |
options | object | No | Validation options |
options.maxFileSize | integer | No | Maximum allowed file size |
options.maxTotalKeys | integer | No | Maximum total keys to import |
options.defaultConflictResolution | string | No | Default conflict strategy: keep_existing or use_imported |
options.allowNewLocales | boolean | No | Allow importing for locales not yet in the project |
Example request
Section titled “Example request”curl -X POST \ -H "X-API-Key: tlk_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "files": [ { "filename": "en.json", "content": "{\"welcome.message\": \"Hello!\"}", "size": 30 } ], "options": { "defaultConflictResolution": "use_imported" } }' \ https://api.comvi.io/api/v1/projects/1/keys/import/validateExample response
Section titled “Example response”{ "validationId": "val_abc123", "files": [ { "filename": "en.json", "detection": { "filename": "en.json", "detectedLocale": "en", "detectedNamespace": "default", "confidence": 0.95, "keyCount": 1, "errors": [], "warnings": [] }, "conflicts": [], "isValid": true } ], "summary": { "totalFiles": 1, "totalKeys": 1, "uniqueKeys": 1, "totalConflicts": 0, "validFiles": 1, "invalidFiles": 0 }, "errors": [], "warnings": []}Step 2: Re-validate (optional)
Section titled “Step 2: Re-validate (optional)”After the user adjusts file-to-locale mappings in the UI, re-validate to detect new conflicts.
POST /api/v1/projects/:projectId/keys/import/revalidateRequest body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
validationId | string | Yes | Validation ID from step 1 |
fileMappings | object[] | Yes | Updated file-to-locale/namespace mappings |
fileMappings[].filename | string | Yes | Filename |
fileMappings[].locale | string | Yes | Target locale code |
fileMappings[].namespace | string | No | Target namespace |
conflictResolutions | object[] | No | Pre-resolved conflicts |
Step 3: Commit import
Section titled “Step 3: Commit import”Commit the validated import with conflict resolutions.
POST /api/v1/projects/:projectId/keys/import/commitRequest body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
validationId | string | Yes | Validation ID from step 1 |
fileMappings | object[] | Yes | File-to-locale/namespace mappings |
conflictResolutions | object[] | Yes | Resolved conflicts |
options.dryRun | boolean | No | Simulate import without writing data |
options.progressTrackingId | string | No | ID for tracking import progress via polling |
Example request
Section titled “Example request”curl -X POST \ -H "X-API-Key: tlk_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "validationId": "val_abc123", "fileMappings": [ { "filename": "en.json", "locale": "en", "namespace": "default" } ], "conflictResolutions": [], "options": { "dryRun": false } }' \ https://api.comvi.io/api/v1/projects/1/keys/import/commitExample response
Section titled “Example response”{ "success": true, "results": { "added": 10, "updated": 5, "skipped": 0 }, "conflictsSummary": { "total": 2, "keepExisting": 1, "useImported": 1 }, "details": [ { "filename": "en.json", "locale": "en", "namespace": "default", "added": 10, "updated": 5, "skipped": 0, "errors": [] } ], "errors": [], "warnings": [], "duration": 1250.5}Track import progress
Section titled “Track import progress”For large imports, poll the progress endpoint to track status.
GET /api/v1/projects/:projectId/keys/import/progress/:trackingIdExample response
Section titled “Example response”{ "status": "running", "totalFiles": 5, "processedFiles": 3, "currentFile": "de.json", "results": { "added": 150, "updated": 30, "skipped": 0 }, "startedAt": "2025-01-16T14:00:00.000Z"}Import translations (CLI flow)
Section titled “Import translations (CLI flow)”The CLI flow is a simpler two-step process designed for automation: validate, then commit.
CLI validate
Section titled “CLI validate”POST /api/v1/projects/:projectId/import/validateRequest body
Section titled “Request body”{ "namespaces": { "default": { "en": { "welcome.message": "Hello!", "welcome.subtitle": "Get started" }, "uk": { "welcome.message": "Привіт!" } } }}CLI commit
Section titled “CLI commit”POST /api/v1/projects/:projectId/import/commitRequest body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
namespaces | object | Yes | Translation data keyed by namespace, locale, key |
options.conflictResolution | string | Yes | keep_local, keep_server, or fail |
options.createNamespaces | boolean | No | Create namespaces that do not exist |
options.deleteOrphans | boolean | No | Delete keys not present in the import data |
Error codes (import)
Section titled “Error codes (import)”| Status | Error | Description |
|---|---|---|
400 | VALIDATION_ERROR | Invalid import data or file format |
401 | UNAUTHORIZED | Missing or invalid authentication |
403 | FORBIDDEN | No permission to import into this project |
403 | LIMIT_EXCEEDED | Import would exceed translation key limit for the current plan |