Set up software localization projects in the Smartcat developer portal

Overview

In addition to regular document-based projects, Smartcat offers a different way of managing keys (strings) that is more suitable for software localization projects.

  • Software keys (strings) are managed on Smartcat, so it becomes the source of truth for all of your software copy

  • UX writers and product managers change the copy themselves, without distracting developers

  • Developers act as content consumers by exporting the needed subset of keys in a format of their choice

  • Developers can import source strings and translations in various developer file formats, and export translations in various file formats as well

  • REST API and CLI offer integration with CI/CD pipelines


Software localization workflow

Here is a typical workflow for a software localization process:

  1. Create collections that will contain keys with unique identifiers

  2. Import keys via API into an existing or new collection (JSON, YAML, iOS Strings, Android XML, and LocJSON). You can do this at the beginning to populate the initial project data

  3. Keys with ICU MessageFormat syntax can be converted to individual segments with plural forms or imported as is

  4. You can add labels to all imported segments

  5. Create or modify keys (segment source and identifiers) inside the CAT editor

  6. You can create new keys with plural forms right in the editor

  7. You can add labels to segments in the editor

  8. Upload screenshots or provide additional context information for segments right from the editor

  9. Translate content and assign suppliers using tasks, as with usual projects

  10. Export keys via API or UI from the editor (JSON, YAML, iOS Strings, Android XML). Plural forms are converted to ICU MessageFormat syntax

At the end of this flow, your translated keys are ready to export back into your codebase.

Diagram of the software localization workflow in Smartcat


Supported file formats

Smartcat supports importing keys from the following file formats:

  • JSON

  • YAML

  • Android XML

  • iOS Strings

  • LocJSON (see below)

LocJSON is a JSON-based file format that Smartcat uses for integration purposes. It is extendable and allows external integrations to pass a list of units (keys + source text + optional translations), and to associate metadata with each unit, such as comments or maximum string length per unit. Smartcat automatically identifies this format by the .locjson file extension.

See LocJSON file format reference for more information

Smartcat supports exporting keys to the following file formats:

  • JSON (flat or structured)

  • YAML (flat or structured)

  • Android XML

  • iOS Strings


Create a software localization project

  1. On the home page, click Create software localization project

    Home page with the Create software localization project option

  2. Enter a project name, for example My App, specify one source language and a list of target languages, and click Create project

New project wizard with name, source language, and target language fields

📌 You can change the list of target languages later at any time, but a project can have only one source language, and the source language cannot be changed once the project is created.

Once the project is created, you see a project Overview page. A default collection called main is created and selected automatically.

Project Overview page with the default main collection selected


Import and export methods

Smartcat supports the following ways to import your existing keys from various file formats:

  • Using Smartcat CLI

  • Using the public API (and standard tools like curl)

  • Directly through the Smartcat UI

The same methods are supported for exporting:

  • Using Smartcat CLI

  • Using the public API (and standard tools like curl)

  • Directly through the Smartcat UI

Smartcat CLI (command-line interface) is a tool available for all popular platforms (Windows, macOS, Linux) that you can run from the command line and from CI/CD scripts to perform certain actions automatically. Read more about the CLI here: Smartcat CLI.


Using the Smartcat CLI

Per-folder configuration file

For convenience, you can create a file called .smartcat in the folder you run Smartcat CLI from. In this file you can put information about your Smartcat server, workspace, project, and API key (all fields are optional).

Example file:

{
  "Server": "https://smartcat.com",
  "Workspace": "fd104ef5-cbe7-1459-c8ac-237d99a3c614",
  "Project": "446dfcf0-e699-4c91-a7ee-40e1237a9f81",
  "ApiToken": "1_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}

Once you do so, this information overrides your user settings. Such a configuration file lets you skip specifying --project xxxxxxxx in every CLI command invocation.

Import with the CLI

Importing keys is done with the smartcat import command. This example shows the actual project identifier, and you can use it as a starting point. If you have a file called en/strings.json (paths can be relative to your current directory), then the following command imports all the keys from that JSON file into your newly created project, into the main collection (the default collection name), while also giving the android label to all imported keys.

smartcat import en/strings.json --language en --label android

Similarly, you can import translations from an existing file that has the same keys:

smartcat import zh-Hans/strings.json --language zh-Hans

💡 Run smartcat import --help for a list of all available import options.

Export with the CLI

Exporting is performed through the smartcat export command. The following example exports the specified target languages and gives them file names as defined in the output template.

smartcat export --languages es,zh-Hans --output-file-path-template 'strings-{LANGUAGE}.json'

💡 Run smartcat export --help for a list of all available export options.


API reference

📌 Most topics regarding authentication and basic API usage are described in the API guides — check this documentation before proceeding. The API reference for import/export is below. The API reference for other API methods is available at developers.smartcat.com/en/api.

Postman collection with API examples

For your convenience, Smartcat provides a Postman collection of API requests that you can experiment with:

V2 Software localization workflow.postman_collection.json

Before using the examples, update the values for several variables used in this collection:

Postman collection variables to update before running the API examples

  1. accountID can be obtained from your Smartcat workspace (see Settings → API)

  2. apiToken can be generated on the same Settings → API page

  3. apiServer is one of the servers your workspace is located on (look up the domain you see when working with your workspace). It can be one of the following:

  4. smartcat.com (Europe)

  5. us.smartcat.com (USA)

  6. ea.smartcat.com (Asia)

  7. projectID is the ID of the project you run import/export against. Once you create a project, its URL looks like https://smartcat.com/projects/6c58e1f5-61c6-43dc-9b83-8d635edbd50c/overview. Here, 6c58e1f5-61c6-43dc-9b83-8d635edbd50c is the project ID

To try the workflow end to end:

  1. Use the import API call (see the Import keys Postman example) to import this document into a newly created project: with_plural_hints.locjson. This automatically creates a collection called main in that project

  2. Open the Files tab in your project, where you see the main collection. Click its name to open it in the editor. Here you can add new keys, and edit or delete existing ones

  3. Import one of these files using the same import API call to add or update keys (this merges changes from those files into your collection of keys):

  4. incremental_add_one_key.locjson

  5. incremental_update_one_key.locjson

  6. Export translated keys back. Export is a two-step process:

  7. Export request (see the Export keys Postman example). Here you specify the needed set of languages and the output file format. This request returns the ID of the asynchronous export task, which is automatically captured by the Postman automation script

  8. Download request (see the Download export results Postman example). This returns the contents of your file. If you request one language, the document is returned as is in the response body. If you request multiple documents, you get a ZIP file with multiple files inside

After these steps, you have imported, edited, and exported a set of localization keys through the API.

Import keys endpoint

POST /api/integration/v2/project/{projectId}/import HTTP/1.1
Content-Type: multipart/form-data
Accept: text/plain

Starts an async import of multiple files into the given project and branch. The body consists of a number of parts with the following headers:

Content-Disposition: form-data; name="file"; filename="path/to/file"
Content-Type: text/plain

Parameters

Name In Type Required Description
projectId path string(uuid) true Project identifier
collection query string false Target collection (optional, "main" as default)
language query string false Language of the imported files
target-languages query string false Comma-separated list of target languages
format query string false Specifies the file format used to import the file (optional)
completion-state query string false Imported translation confirmation mode
labels query string false Comma-separated labels attached to the created/updated segments (even if the text is not changed)
path-separator query string false Path separator string (optional)
skip-conflicting-values query boolean false Specifies how to deal with situations when the same key has a different value
overwrite-conflicting-values query boolean false When the same key has a different value in the imported file and in Smartcat, use the value from the file
auto-file-labels query boolean false Should Smartcat automatically create labels from file names?
delete-missing-keys query boolean false Delete keys that are not present in the imported files
body body UploadedFile true Files for import

Detailed descriptions

format — specifies the file format used to import the file. Smartcat tries to guess the file format from its extension:

  • json — flat key-value format

  • structured-json — tree-like format; see also path-separator

  • yaml — flat key-value format

  • structured-yaml — tree-like format; see also path-separator

  • ios-strings — iOS .strings resource file format

  • android-xml — Android XML resource file format

path-separator — path separator string, used to construct keys for nested JSON objects (defaults to "/"). In the following example JSON file, when the "value" string is imported, its key name is "object/my-key".

{
  "object": {
    "my-key": "My value"
  }
}

target-languages — comma-separated list of target languages (optional, all target languages of the project by default, can only be specified when importing the source).

  • An empty list of languages produces a 400 bad request error with an appropriate reason text

  • An incorrect language code produces a 400 bad request error with an appropriate reason text

  • If a language did not exist in the project, it is created (but not added as a target to any existing collections)

  • If a language did not exist in the collection (the target collection existed before), it is added as a target to the collection

completion-state — imported translation confirmation mode:

  • draft — no confirmation

  • intermediate — confirm on the first project stage

  • final — confirm on all project stages

Responses

Status Meaning Description Schema
200 OK Request has been successfully completed Response with the import ID
400 Bad Request See the detailed description below None
403 Forbidden See the detailed description below None

HTTP 400 returns if:

  • The required language parameter is missing

  • The request body contains no files

  • skip-conflicting-values and overwrite-conflicting-values are specified at the same time. Choose one option

  • The passed language is completely unrecognizable by Smartcat

  • The passed language is neither a source language nor one of the target languages

  • The format value is invalid. Allowed values are: json, yaml, ios-strings, android-xml, locjson

  • The path-separator parameter is specified for a file format other than json or yaml

HTTP 403 returns if:

  • The requested project does not belong to the authenticated account

  • You try to import into a non-developer project

  • You try to import into a personal account

Get import result

GET api/v1/project/import-result/{importId} HTTP/1.1
Accept: text/plain

Returns the current import status if the import task exists.

Result model:

{
  "status": "pending" | "inprogress" | "completed" | "failed",
  "errors": { "error": "string", "fileName": "string" }[],
  "keysCreated": 0,
  "keysUpdated": 0,
  "keyValuesNotChanged": 0,
  "keysWithoutSource": 0,
  "conflictingKeyValues": {
    "key1": ["valueA", "valueB"],
    "key2": ["valueC"]
  }
}

Responses

Status Meaning Description Schema
200 OK Request has been successfully completed Returns current import status
404 Not Found The export ID doesn't exist None

Export keys endpoint

POST /api/integration/v2/project/{projectId}/export HTTP/1.1
Content-Type: multipart/form-data
Accept: text/plain

Starts an async export of multiple files for the given project and branch. Returns HTTP 200 with an export ID if the export has started.

Parameters

Name In Type Required Description
languages query string false Comma-separated list of languages to export (allows multiple, all target languages as default)
collections query string false Export from one collection (main as default)
path-separator query string false Path separator string, used to reconstruct nested JSON objects (defaults to "/")
completion-state query string false Minimal key completion state (final by default)
fallback-to-default-language query string false Incomplete translations: download segments that passed through all translation stages (default)
export-incomplete-as-blank query string false Incomplete translations: export blank values when no translation is ready
skip-incomplete-keys query string false Incomplete translations: do not export keys that have no translations (default for "android-xml" export file type)
format query string false Export format (json by default)
include-default-language query string false Should the default language be included in the export?
output-file-path-template query string false Output file path template
zip query string false Force export in a ZIP archive, even when downloading a single file
modified-since query string(date-time) false Export keys that were changed after the datetime
labels query string false Comma-separated list of labels to export keys that are marked with labels

path-separator — path separator string, used to reconstruct nested JSON objects (defaults to "/"). If there is a key "object/my-key" with the value "My value", then exporting a structured JSON file gives the following result:

{
  "object": {
    "key": "value"
  }
}

completion-state — minimal key completion state (final by default):

  • final — download segments that passed through all translation stages (default)

  • intermediate — download segments at the last confirmed stage

  • draft — download any translations, even unconfirmed ones

What to do with incomplete translations:

  • fallback-to-default-language — return default language values instead of translations (default)

  • export-incomplete-as-blank — export blank values when no translation is ready

  • skip-incomplete-keys — do not export keys that have no translations (default for "android-xml" export file type)

format — export format (json by default):

  • json — flat key-value format (default)

  • structured-json — tree-like format; see also path-separator

  • yaml — flat key-value format

  • structured-yaml — tree-like format; see also path-separator

  • ios-strings — iOS .strings resource file format

  • android-xml — Android XML resource file format

Responses

Status Meaning Description Schema
200 OK Request has been successfully completed Returns export ID
400 Bad Request See detailed description below None
403 Forbidden The requested project does not exist in the authenticated account None

HTTP 400 returns if:

  • The required language parameter is missing

  • The path-separator parameter is specified for a format other than structured-json or structured-yaml

  • The passed language is completely unrecognizable by Smartcat

  • The passed language is neither a source language nor one of the target languages

  • Any passed label is empty

  • The completion-state value is invalid. Allowed values are: final, intermediate, draft

  • The format value is invalid. Allowed values are: json, structured-json, yaml, structured-yaml, ios-strings, android-xml

  • fallback-to-default-language, export-incomplete-as-blank, or skip-incomplete-keys are specified at the same time. Choose one option

File path template

output-file-path-template — output file path template. Specifies how the output files are named and located. You can use the {LANGUAGE} and {LABEL:PREFIX} placeholders to customize the output.

The {LABEL:PREFIX} placeholder lets you export keys that have the PREFIX value as their label prefix, and use the label suffix to determine the file name. For example:

  • Segment A has a label file:main.json

  • Segment B has a label file:errors.json

Specifying resources/{LABEL:file} as the path template and JSON as the export format results in a ZIP file with the following structure:

  • resources/main.json — contains segment A

  • resources/errors.json — contains segment B

Defaults:

  • strings-{LANGUAGE}.json for the "json" file format

  • strings-{LANGUAGE}.yaml for the "yaml" file format

  • {LOCALE:IOS}.lproj/values.strings for the "ios-strings" file format

  • src/main/res/values-{LOCALE:ANDROID}/strings.xml for the "android-xml" file format

Get export result

GET /api/integration/v1/document/export/{exportId} HTTP/1.1
Accept: text/plain

Returns the export result file.

Responses

Status Meaning Description Schema
200 OK Request has been successfully completed Returns export result file — a single file if export started with one target language, a ZIP archive otherwise
204 No Content Export is not available yet None

Add new target languages

POST /api/integration/v1/project/{projectId}/software-localization/targets HTTP/1.1
Accept: text/plain

Adds target languages to the software localization project. If any of the specified target languages does not exist in the project, it is created but not added as a target to any existing collections. If any of the specified languages does not exist in the collection (the target collection existed before), it is added as a target to the collection.

Parameters

Name In Type Required Description
target-languages query string true Comma-separated list of target languages to add. See the list of language codes here

Responses

Status Meaning Description Schema
200 OK Request has been successfully completed None
400 Bad Request Bad request None

HTTP 400 returns if:

  • The list of languages is empty

  • Any one of the language codes is incorrect


Using curl instead of the CLI

Because Smartcat offers the same import/export functionality via its REST API, you can also use curl or an equivalent tool available in your operating system to do basic automation tasks without installing Smartcat CLI. This may be a preferred option in organizations that have strict security requirements.

Below is an example Shell script that uses curl and zip to export keys from Smartcat:

#!/bin/sh
auth="Authorization: Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX="
task=$(curl --silent --location --request POST 'https://smartcat.com/api/integration/v1/project/446dfcf0-e699-4c91-a7ee-40e1237a9/export' \
--header "$auth" --header 'Content-Type: application/json' --data-raw '{
  "languages": ["es", "zh-Hans"]
}' | tr -d '"')
echo "Export task ID: $task"
sleep 2 # wait till export is done
curl --silent --location --request GET "https://smartcat.com/api/integration/v1/document/export/"$task --header "$auth" -o product-a.zip
unzip product-a.zip

Working with plurals

Smartcat supports two ways of handling plurals:

  • Natively (as independent segments in the editor)

  • Via ICU MessageFormat syntax

When you open a collection of keys in the CAT editor, you can add new keys, and when you do so, specify whether the key needs to be created with all plural forms. When exporting keys, plural forms are converted into an ICU MessageFormat-compatible string.

When importing a LocJSON file, you can specify whether keys containing ICU MessageFormat syntax should be parsed and converted into individual segments in Smartcat, or kept as is so that you can edit the raw string. For raw ICU MessageFormat strings, you can plug in an interactive previewer/validator for this format.

Still need help?

Our support team responds within one business day.

Open a support case