Main menu

Loco Developer API

Our API makes localizing your software with Loco even more powerful.

If you have any problems or requests, just ask.

API Reference Examples File Formats API Explorer

What can I do with it?

The main thing you'll want to do with the Loco API is pull translation files into whatever you're building. Check out the Export API methods and the example below.

If you'd like to automate your Loco workflow further, the API allows you to programmatically add assets, manage locales and make translations. Check out some examples or browse all the available methods.


No OAuth dance required. Working with a Loco project requires just a simple API key sent over SSL. See authentication reference

You can generate API keys from your Loco project dashboard, see here for full details.

API Resources

Loco API resources are grouped into endpoints for working with assets, locales and translations, as well as importing and exporting translation files. See the full endpoint reference for details of every API method, or explore them in the test console below.

Rate limits

The REST API is not currently rate-limited, and we're hoping to keep it that way for as long as possible. See here for full details.


Currently the only official Loco API client is for PHP. Get it from Github or Packagist.

See our list of community libraries in other languages.


Here are some workflow examples. We've got a brand new project, so we'll add some assets and locales and make some translations. These examples use command line cURL. Responses in green are simplified.

Importing an existing file

The most common starting point for using Loco is to get an existing batch of source strings into your dashboard. This example imports a Gettext POT file into a fresh project which need only contain our default language for now.

$ curl --data-binary @messages.pot '' -u <your_key>:
HTTP/1.1 200 Ok
{ "message": "100 translations imported, 100 new assets" ... }

This is the quickest way to get started, but the API provides more fine-grained control than simply importing and exporting whole files. See below for some more specific actions you could automate.

Add a new translatable asset

Most operations in Loco revolve around assets. Importing them from an existing file is the quickest route, but the API also lets you add them individually. Here we post the string "Hello World" to the assets collection to create a new translatable item.

$ curl -F'id=hello' -F'text=Hello World' '' -u <your_key>:
HTTP/1.1 201 Created
{ "id":"hello", "type":"text", "progress":{"translated":1 ... }
  • A default translation is created automatically, so the progress field shows that one translation exists.
  • If we hadn't specified id=hello a unique ID would have been automatically generated. You'll need this to reference the asset later.

Add a new project locale

Our project is only in English at the moment, so here we add Spanish by posting to the locales collection.

$ curl -F 'code=es' '' -u <your_key>:
HTTP/1.1 201 Created
{ "code":"es", "name":"Spanish", "plurals": { "length":2, "equation":"n != 1", "forms":["one","other"] } ... }
  • The response is a locale object containing useful metadata including plural forms.

Make a translation

Now that we have an asset to translate and something to translate it into, we can create our first translation. Here we post the translated text to the translation endpoint. Note that the translation is posted as the raw request body.

$ curl --data-binary 'Hola Mundo' '' -u <your_key>:
{ "id":"hello", "translated":true, "translation":"Hola Mundo", "revision":1, ... }
  • Note the revision number is "1" because it's the first Spanish translation of this asset.
  • Repeated calls to this method will simply update the translation and increment the revision number.

Export translations

Finally we want to export all our translations to the file format we're using in our software. Here we use the Export API to pull our Spanish translations into a Gettext PO file. See the full list of export formats below.

$ curl '' -u <your_key>:
msgid "Hello World"
msgstr "Hola Mondo"

You'll notice that the PO file hasn't used use our unique "hello" ID. This is the nature of PO files - the source text is used instead of a language-agnostic key. Compare that with what an Android XML file would look like for our English translations:

$ curl '' -u <your_key>:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string name="hello">Hello World</string>

Loco can work with or without language-agnostic keys. The import and export APIs provide you full control over this, so you can manage the same set of translations over multiple platforms.


Loco handles plural forms as assets in their own right, but there are specific endpoints for binding them together. Here we create a singular asset and then link a plural form by posting to its plurals collection.

$ curl -F'id=apple' -F'text=An Apple' '' -u <your_key>:
{ "id":"apple", "type":"text", "progress":{"translated":1 ... }
$ curl -F'pid=apples' -F'text=%d apples' '' -u <your_key>:
{ "id":"apples", "type":"text", "progress":{"translated":1 ... }
  • Note that when binding the plural form we specify pid because the id parameter is already bound to the singular form in the URI path.

Export formats

The Export API offers more than just JSON responses. You can output your translations to a wealth of file types and language pack formats.

File extensions

The following language pack formats can be exported by specifying the relevant file extension:

  • .pot .po .mo Gettext PO, POT and binary MO
  • .tmx Translation Memory eXchange
  • .xlf .xliff Localization Interchange File Format
  • .csv Comma separated values
  • .sql MySQL INSERT statements
  • .resx ResX for .NET framework
  • .html HTML table
  • .strings iOS Localizable strings
  • .stringsdict iOS plural rules
  • .plist .bplist Apple property list XML and binary formats
  • .properties Java properties file
  • .ts An XML format for Qt Framework
  • .res .txt ICU Resource Bundles (binary and source)

The following extensions are used for mutiple formats, but have a default:

Alternative styles

The {format} parameter can be used to export a more specific style of some of the formats above –

JSON formats

In addition to the default JSON format, you can specify ARB, Chrome, Jed and i18next language pack formats as follows:{locale}.arb{locale}.json?format=jed{locale}.json?format=chrome{locale}.json?format=i18next4

YAML formats

Several YAML formats are available - simple, nested and rails. The simple format is flat and only exports a single locale. The nested format supports multiple locales and contains a top-level namespace.

The rails format is specifically for Ruby on Rails and follows the conventions of the i18n module.{locale}.yml?format=rails{locale}.yml?format=nested

XML formats

In addition to the default Android format, specify java to produce Java properties XML and tizen to produce Tizen formatted XML.{locale}.xml?format=java{locale}.xml?format=tizen

Other XML formats have their own specific file extensions, such as .tmx .xlf .resx .plist .ts

iOS Localization files

In addition to the strings and stringsdict extensions, you can export an iOS-specific XLIFF file suitable for Xcode's "Import Localizations" feature:{locale}.xliff?format=xcode

PHP language packs

In addition to the default Zend format, you can specify Symfony or Code Igniter or output simple constant definitions.{locale}.phps?format=symfony{locale}.phps?format=codeigniter{locale}.phps?format=constants

Note that the .phps extension is used to indicate source code output, but you can use .php if you prefer.

Import formats

The Import API can create assets and translations from existing language pack files of various types.

File extensions

The following language pack formats can be imported by specifying the relevant file extension:

  • .po .pot .mo Gettext PO, POT and binary MO
  • .ts TS for Qt Framework
  • .tmx Translation Memory eXchange
  • .xlf Localization Interchange File Format
  • .resx ResX for .NET framework
  • .plist .blist Apple property list and binary plist
  • .strings iOS Localizable strings
  • .properties Java properties file
  • .res .txt ICU Resource Bundles (binary and source)

The following file formats can differ in structure, so Loco will attempt to parse numerous variations:

  • .yml flat and nested structures for Symfony and Ruby on Rails
  • .xml Android, Java and Tizen XML structures
  • .php any PHP source code, with specific support for Symfony, Zend and Code Igniter language packs
  • .json any key/value pairings, with specific support for ARB, Jed, Chrome and i18next language packs.
  • .csv must follow a similar structure to Loco's CSV exports.


If you're importing a generic format such as JSON, Loco gives you some control over what's imported.

Consider a structure like {"foo":"Bar"}. This could be an asset with ID "foo" mapped to the English translation "Bar", or it could be an English word "foo" mapped to the French translation "Bar".

The {index} parameter specifies whether the translations in your file are indexed by asset IDs or source texts. In combination with the {locale} parameter, the ambiguous example above can be handled however it was intended.

The following form tells Loco that the file is indexed by asset IDs and the texts should be imported as English translations:{ext}?index=id&locale=en

The following form tells Loco that the file is indexed by source language texts and you also want to import the translations as French:{ext}?index=text&locale=fr

Note that specifying index=text implies that default language "translations" (i.e. source texts) will be created if they don't exist already. When specifying index=id you must set the {locale} parameter so Loco knows what language the file contains.

Asynchronous import

If you're importing a large file, it's recommended to specify the {async} parameter. Setting this tells Loco to run the import operation in the background. This will avoid connection timeouts if the import takes more than a few seconds.

The following example imports a POT file asynchronously.

The Location header obtained from the response can be used to check the progress of the import. That URL takes the following form:{id}

Once the operation is complete you will get a response like this:

{ "progress": 100, "success": "100 translations imported", "error": "" }

API Explorer

You can try the Loco API directly from this page without writing any code, but you'll need an API key for the endpoints requiring authentication.

Version 1.0.28. The Loco API is discoverable here in Swagger format.

Need help?

Try our help centre, or ask us a question

Contact us Developer support