Imports and exports

Upload files and download translations as asynchronous jobs.

Imports and exports run as asynchronous jobs. You start a job and get 202 Accepted right away, with the job in the response: {"object_type": "JOB", "job_type": "IMPORT", "data": {...}}. The job's ID is data.id. Poll the job until it reaches a final status. The same pattern applies to other long-running work, such as project moves and backup restores.

Step-by-step versions with Shell and Python code are in the recipes Import a file and Export translations.

Find the branch

Files belong to a project branch. The project's default_branch_id is the branch most integrations work on:

curl "https://api.lingohub.com/v2/projects/$PROJECT_ID" \
  -H "Authorization: Bearer $LINGOHUB_API_KEY"

To work on another branch, list them with GET /v2/projects/{projectId}/branches.

Import a file

Upload the file as multipart/form-data. A file whose name ends in .zip is imported as an archive of files.

curl -X POST "https://api.lingohub.com/v2/branches/$BRANCH_ID/imports" \
  -H "Authorization: Bearer $LINGOHUB_API_KEY" \
  -H "Idempotency-Key: $IMPORT_KEY" \
  -F "[email protected]" \
  -F "language_code=en" \
  -F "path=src/i18n"
Form fieldRequiredMeaning
fileYesThe file or .zip archive to import.
language_codeNoLanguage of the file, or of every file in the archive. Omit it to detect the language from each file's name and path.
pathNoFolder to import into, for example src/i18n/de. Omit it to import at the project root.

Then poll the import and read its entries:

curl "https://api.lingohub.com/v2/imports/$IMPORT_ID" \
  -H "Authorization: Bearer $LINGOHUB_API_KEY"

curl "https://api.lingohub.com/v2/imports/$IMPORT_ID/entries" \
  -H "Authorization: Bearer $LINGOHUB_API_KEY"

To check a file before you import it, use POST /v2/branches/{branchId}/imports/inspect. After an import, GET /v2/imports/{importId}/resource-changes and GET /v2/imports/{importId}/text-changes list what it changed.

Export translations

Request an export, poll it, then download the file from its download_url:

curl -X POST "https://api.lingohub.com/v2/branches/$BRANCH_ID/exports" \
  -H "Authorization: Bearer $LINGOHUB_API_KEY" \
  -H "Idempotency-Key: $EXPORT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"language_codes": ["de", "fr"]}'

curl "https://api.lingohub.com/v2/exports/$EXPORT_ID" \
  -H "Authorization: Bearer $LINGOHUB_API_KEY"

The download URL is pre-signed and expires at download_url_expires_at. Read the export again to get a fresh link.

Job statuses

StatusMeaning
QUEUED, PROCESSINGStill running. Poll again later.
SUCCEEDEDFinished.
PARTIALLY_SUCCEEDEDFinished, but some of the work failed. An export may still have produced a file.
FAILEDFailed. Partial changes may already be applied.
CANCELLEDCancelled. A queued import can be cancelled with POST /v2/imports/{importId}/cancel.
SKIPPEDEnded without running. status_details gives the reason.

Good practice

  • An accepted job can still fail or only partly succeed. Don't treat 202 Accepted or a download URL alone as success.
  • After a partial or failed result, read status_details, all pages of the job's entries and its logs (/logs) before you retry.
  • Keep the job IDs you get back, so that a client interruption doesn't force you to submit the work again.
  • Send an Idempotency-Key with each import and export request. See Safe retries and conditional updates.

Did this page help you?