Version: 1.0.3
Website: https://www.applanga.com
To make requests to the Applanga API you first need to create a Project in the Applanga Dashboard.
Then you need to request an API Access Token. Go to the Project Settings (click Project Settings in the Project overview), and click Show API Token.
Note: all GET
Requests are cached via CDN thus any change related to strings or tags will take about 10 minutes before you see it in the response.
With your API Token you can now query the API at https://api.applanga.com/v1/api?app={app_id}
. To authenticate your request you need to set the Authorization header to carry your API Token in the bearer format (as described here https://tools.ietf.org/html/rfc6750#page-5 ). The value of the Authorization header needs to be 'Bearer {apiToken}'
. Example: Authorization: Bearer xxxxxxxxxxxxxxxxxxxx!xxxxxxxxxxxxxxxxxxxxxx
You also need to pass the id of your app to the query with the app parameter. https://api.applanga.com/v1/api?app={app_id}
. The app_id is the first part of your API token until the !
e.g. if your API Token would be 54e49f570de187711f9a5936!64d6e85c0111f758748898e3181a25b7
the app_id is 54e49f570de187711f9a5936
.
For API write access, as an additional security measure you have to specify a list of authorized IP's or IP ranges. Go to your Project in the Applanga Dashboard, click Project Settings, if you have API access you will have an input field below Show API Token which will allow you to enter IP addresses (ipv4 and ipv6) or address ranges in CIDR Notation (https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing). To allow write access from all ipv4 addresses add 0.0.0.0/0, for all ipv6 addresses ::/0. For unrestricted access add both. Not adding any IP addresses/ranges will block all write access.
Optional payload compression for API requests is by default supported.
To receive a response with a compressed payload you only need to set the Accept-Encoding
header to gzip
on a request.
The client then receives the response with a content-encoding: gzip
response header and GZIP-encoded payload.
Send a GET request to https://api.applanga.com/v1/api?app={app_id}
. The API will identify your App and authenticate the token and return your App translation data.
Request example with curl:
# Unix
$ curl 'https://api.applanga.com/v1/api?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>'
# Windows
$ curl "https://api.applanga.com/v1/api/app=<your-app_id>" -H "Authorization: Bearer <your-api_token>"
# HTTP/1.1 200 OK
> {
> "_id":"yourAppId",
> "__v":"1.0",
> "draftModeEnabled":true,
> "collectMissingEnabled":false,
> "baseLanguage":"en",
> "name":"yourAppName",
> "data":{
> "en":{
> "main":{
> "version":"25",
> "entries":{
> "MenuTitle1 key":{
> "d":"Menu Title1 draft",
> "v":"Menu Title1 value",
> //[optional]
> "desc": "description",
> "updatedAt":"2020-02-26T15:00:08.676Z",
> "userId":"5e5688e0d7xxxx73391817c8",
> "src":"/en/menu_strings.xml",
> "meta": {
> "metaKey1": "metadata value 1",
> "metaKey1": "metadata value 2"
> }
> },
> "MenuTitle2 key":{
> "d":"Menu Title2 draft",
> "v":"Menu Title2 value",
> "updatedAt":"2020-02-25T15:00:08.676Z",
> "userId":"5e5688e0d7xxxx73391817c8",
> "src":"/en/menu_strings.xml"
> },
> ...
> },
> ...
> },
> ...
> }
> }
> }
For typical apps without configured groups the response will only contain one group named "main".
The API is using a Content Delivery Network for fast and reliable content distribution. It is updated in fixed intervals and it therefore might take up to 10 minutes until changes made in the dashboard appear live in the api.
To limit the response data to certain groups, and/or languages, and/or tags, and/or status you can add query parameters requestedLanguages, requestedGroups, requestedTagIds and requestedStatus, as json string arrays which have to be urlencoded as well. An Example for requested group main and languages en and de : https://api.applanga.com/v1/api?app={app_id}&requestedGroups=[%22main%22]&requestedLanguages=[%22en%22,%22de%22]&requestedTagIds=[%22tag_id_1%22, %22tag_id_2%22]&requestedStatus=[1,%202]
.
If you do not request any languages or groups, all groups and languages will be returned. If you have not activated groups and created additional groups, all your translations will be in group main.
It is also possible to include additional data or removing data from the response by adding additional query parameters.
statusDescription
, which is an object that maps translation status description to status value. An example of what this could look like is as follows"statusDescription": {
"nostatus/new": 0,
"accepted": 1,
"needs review": 2,
"needs translation": 3,
"rejected": 4,
"in order": 5,
"testing": 1001,
...
}
In the preceding example all the known translation status are present including a custom string status testing
.(default=false)
Example to include additionally src, status and status description: https://api.applanga.com/v1/api?app={app_id}?includeSrc=true&includeStatus=true&includeStatusDescription=true
Send a POST request to https://api.applanga.com/v1/api?app={app_id}
with a json body matching the JSON Schema (http://json-schema.org/) described under JSON Schema for API write access. The API will identify your App and authenticate the token. If your request is authorized the data will be written to your app and a json object describing the changes will be returned. Otherwise you will receive an http error. Don't forget to set the Content-Type: application/json
header.
You can also add a set of options to your request body to specify how the write operation should be performed. The following options can be set as members of an options property in the request body:
2.1. onlyAsDraft: take draft or value from input and store in draft. default: false
2.2. onlyIfTextEmpty: only write draft or value if its empty. default: false
2.3. skipLockedTranslations: don't change locked translations. default: false
2.4. setStatus: set status of all submitted transations to possible values: 0 (remove status); 1 (accepted); 2 (needs review); 3 (needs translation); 4 (rejected) or a Custom workflow status. default: no status change
2.5. setStatusOnNewStrings: set status of new transations alone, to possible values: 0 (remove status); 1 (accepted); 2 (needs review); 3 (needs translation); 4 (rejected) or a Custom workflow status. default: no status change. Note that if setStatus is set then this is ignored.
2.6. setStatusOnChangedStrings: set status of changed transations alone, to possible values: 0 (remove status); 1 (accepted); 2 (needs review); 3 (needs translation); 4 (rejected) or a Custom workflow status. default: no status change. Note that if setStatus is set then this is ignored.
2.7. skipEmpty: skip keys when the draft and value are empty. default: true
2.8. createNewLanguages: create non existent languages. If a language that does not exist in the project is included, then setting this option to true will ensure the language is created and the corresponding strings are uploaded default: false.
Also in case the non existent languages are custom languages and not supported by Applanga then the display name for the language needs to be set in the request body under languageDisplayNames. If the the display names are missing for any of those languages then an error response will be returned. For example if we set a custom language xx-ZZ
which has a display name Display name for xx-ZZ
for string uploads then the request body should include the following
{
"options": {
"createNewLanguages": true
},
"data": {
"xx-ZZ" {
"main": {
"entries": {
"key1":{
"d":"draft1",
"v":"value1",
"src":"/src/File1"
},
}
}
}
},
"languageDisplayNames": {
"xx-ZZ": "Display name for xx-ZZ"
}
}
2.9. createNewGroups: create non existent groups. If a group that does not exist in the project is included, then setting this option to true will ensure the group is created and the corresponding strings are uploaded default: false.
In the following example the non existent group non-existent-group
will created since createNewGroups
is set to true
. If not the api will return an error response.
{
"options": {
"createNewGroups": true
},
"data": {
"xx-ZZ" {
"non-existent-group": {
"entries": {
"key1":{
"d":"draft1",
"v":"value1",
"src":"/src/File1"
},
}
}
}
}
}
Note: The createNewGroups only works if the project has Groups enabled. Groups are by default disabled and must be enabled in the Project Settings. See Groups for more information.
Set a custom name for any language in the request body. In the languageDisplayNames field set language code as the key and the custom language name as the value. The language set here must correspond to one of the languages in the request data or else it will be ignored. Note that the language code must be a valid ISO language code. Applanga supports all ISO 639-1, 639-2, and 639-3 language codes. For more informations where to find them please see: https://www.applanga.com/docs/translation-management-dashboard/adding-and-removing-languages. Addtionally you can also specify a custom language code either as 2 letter lowercase language e.g. "pt" or combined with an uppercase region code e.g. "pt-BR". If the language code is not valid as described above an error response will be returned. As an example if you want to upload some strings for a language xx-ZZ
as shown below
{
"data": {
"xx-ZZ" {
"main": {
"entries": {
"key1":{
"d":"draft1",
"v":"value1",
"src":"/src/File1"
},
}
}
}
}
}
to set the language display of name of xx-ZZ
to Custom display name for xx-ZZ
for example, update the request body like so
{
"data": {
"xx-ZZ" {
"main": {
"entries": {
"key1":{
"d":"draft1",
"v":"value1",
"src":"/src/File1"
},
}
}
}
},
"languageDisplayNames": {
"xx-ZZ": "Custom display name for xx-ZZ"
}
}
Example JSON body for four translations in language en, group main, status set to accepted and only drafts being written (remember to use Content-Type: application/json
as request header):
{
"options":{
"onlyAsDraft":true,
"setStatus":1
},
"data":{
"en":{
"main":{
"entries":{
"key1":{
"d":"draft1",
"v":"value1",
"src":"/src/File1"
},
"key2":{
"d":"draft2",
"v":"value2",
"src":"/src/File2"
},
"key3":{
"d":"draft3",
"v":"value3",
"src":"/src/File3",
"meta": {
"metaKey1": "metadata value 1",
"metaKey2": "metadata value 2"
}
},
"key4":{
"d":"draft4",
"v":"value4",
"src":"/src/File45",
"desc": "description4"
}
}
}
}
}
}
Request Example with curl:
# Unix
$ curl -X POST 'https://api.applanga.com/v1/api?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>' -H "Content-Type: application/json" -d '{"data": { "en": { "main": {"entries": {"key999" :{"v": "api_test"}}}}}}'
# Windows
$ curl -X POST "https://api.applanga.com/v1/api?app=<your-app_id>" -H "Authorization: Bearer <your-api_token>" -H "Content-Type: application/json" -d "{\"data\": { \"en\": { \"main\": {\"entries\": {\"key999\" :{\"v\": \"api_test\"}}}}}}"
# HTTP/1.1 200 OK
> {
> "total":1,
> "added":1,
> "updated":1,
> "tagUpdates":0,
> "groupChanged":0,
> "groupCountChanges":{
> "5e258d3e1f7363cb911dd535":1
> },
> "_additionalData":{
> "skippedEntries":[
>
> ]
> },
> "keys":[
> "key999"
> ]
> }
This describes the format of the json body expected for an API POST request
Also see http://json-schema.org/.
Note: The format returned by a GET request also matches this format, with the addition of a version field to the group data object. For writes also the additional field desc can be set but only in the base language.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Api - Translation data input format",
"description": "A data object describing translation entries ordered by groups and languages",
"type": "object",
"additionalProperties": false,
"required": ["data"],
"properties": {
"options": {
"description": "options describing how to handle the input",
"type": "object",
"additionalProperties": false,
"properties": {
"onlyAsDraft": {
"description": "take draft or value from input and store in draft",
"type": "boolean",
"default": "false"
},
"onlyIfTextEmpty": {
"description": "only write draft or value if its empty",
"type": "boolean",
"default": "false"
},
"skipLockedTranslations": {
"description": "don\"t change locked translations",
"type": "boolean",
"default": "false"
},
"skipEmpty": {
"description": "skip keys when the draft and value are empty",
"type": "boolean",
"default": "true"
},
"createNewLanguages": {
"description": "create non existent languages",
"type": "boolean",
"default": "false"
},
"createNewGroups": {
"description": "create non existent groups",
"type": "boolean",
"default": "false"
},
"setStatus": {
"description": "0->nostatus; 1->accepted; 2->needs review; 3->needs translation; 4->rejected; or a custom workflow status",
"oneOf": [
{
"type": "string",
"enum": ["0", "1", "2", "3", "4"]
},
{
"type": "integer",
"minimum": 0,
"maximum": 4
},
{
"type": "integer",
"minimum": 1001
},
{
"type": "string",
"pattern": "(?!^1000$)^[1-9]\\d{3,}$"
}
]
},
"setStatusOnNewStrings": {
"description": "0->nostatus; 1->accepted; 2->needs review; 3->needs translation; 4->rejected; or a custom workflow status",
"oneOf": [
{
"type": "string",
"enum": ["0", "1", "2", "3", "4"]
},
{
"type": "integer",
"minimum": 0,
"maximum": 4
},
{
"type": "integer",
"minimum": 1001
},
{
"type": "string",
"pattern": "(?!^1000$)^[1-9]\\d{3,}$"
}
]
},
"setStatusOnChangedStrings": {
"description": "0->nostatus; 1->accepted; 2->needs review; 3->needs translation; 4->rejected; or a custom workflow status",
"oneOf": [
{
"type": "string",
"enum": ["0", "1", "2", "3", "4"]
},
{
"type": "integer",
"minimum": 0,
"maximum": 4
},
{
"type": "integer",
"minimum": 1001
},
{
"type": "string",
"pattern": "(?!^1000$)^[1-9]\\d{3,}$"
}
]
}
}
},
"data":{
"description": "top level data object",
"type": "object",
"additionalProperties": false,
"minProperties": 1,
"patternProperties": {
"^[a-zA-Z\-]*$":{
"description": "dataset mapped to a language name",
"type": "object",
"additionalProperties":false,
"minProperties": 1,
"patternProperties": {
".*":{
"description": "dataset mapped to a group name",
"type": "object",
"additionalProperties":false,
"properties":{
"entries": {
"description": "translation data map",
"type": "object",
"additionalProperties":false,
"minProperties": 1,
"patternProperties": {
".*":{
"description": "the actual language entry data",
"type": "object",
"properties":{
"d" : {
"type": "string"
},
"v" : {
"type": "string"
},
"src" : {
"type": "string"
},
"desc" : {
"type": "string"
},
"meta": {
"type": "object",
"patternProperties": {
".*": {
"type": "string"
}
}
}
}
}
}
}
}
}
}
}
}
},
"languageDisplayNames": {
"description": "maps a custom language code to it's display name",
"type": "object"
}
}
}
Send a GET request to https://api.applanga.com/v1/api/screenshots?app={app_id}
. The API will identify your App and authenticate the token and return all the screenshots of the App.
Request example with curl:
# Unix
$ curl 'https://api.applanga.com/v1/api/screenshots?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>'
# Windows
$ curl "https://api.applanga.com/v1/api/screenshots?app=<your-app_id>" -H "Authorization: Bearer <your-api_token>"
# HTTP/1.1 200 OK
> [
> {
> "url": "https://s3.eu-central-1.amazonaws.com/applanga/......jpg",
> "originalName": "CyOrcrgVIAAJLDt.jpg_Test1",
> "mimetype": "image/jpeg",
> "tag": {
> "name": "Test1",
> "created": "2017-11-28T14:16:59.083Z",
> "updatedAt": "2017-11-28T15:12:29.651Z",
> "languageEntryIds": [
> "Test1"
> ]
> },
> "metadata": {
> "width": 480,
> "height": 635,
> "deviceModel": "IPhone",
> "operatingSystem": "iOS",
> "bundleVersion": "1.0",
> "deviceLanguageLong": "English",
> "updatedAt": "2017-11-28T14:17:32.241Z",
> "isBlank": true,
> "stringPositions": [
> {
> "key": "Test1",
> "x": 100,
> "y": 10,
> "width": 200,
> "height": 40,
> "css": "font-family: Helvetica; color: #fefefe;"
> }
> ]
> }
> },
> ...
> ]
Note: The generated url's are only working for 15 minutes for security reasons. Be aware that you have to download the images within that timeframe or redo the request to get newly generated urls.
Send a POST request to https://api.applanga.com/v1/api/screenshots?app={app_id}
with a FormData containing two keys data and file. The API will identify your App and authenticate the token. If your request is authorized the screenshot will be uploaded to your app and a json object describing the changes will be returned. Otherwise you will receive an http error.
Example FormData object (remember to use Content-Type: application/json
as request header):
{
"data":{
"screenTag": "tag99",
"width": 600,
"height": 400,
"deviceModel": "test device model",
"platform": "test platform",
"operatingSystem": "test os",
"bundleVersion": "test bundle version",
"deviceLanguageLong": "en",
"useFuzzyMatching": true,
"stringPositions": [
{
"key": "Key99",
"x": 100,
"y": 10,
"width": 200,
"height": 40
},
{
"text": "myText",
"x": 100,
"y": 300,
"width": 100,
"height": 20
}
]
},
"file":{
"fileName": "test file name",
"mimeType": "image/png",
"data": "buffer from the screenshot file"
}
}
Note: the useOCR
option which enables the detection of string positions on the image is no longer supported. String postions on images ahould be managed on the Applanga dashboard. Find out more information on how to manage screenshots from the dashboard here.
Note: stringPositions with no key
and a text
attribute will try to be resolved via fuzzyMatching only if the useFuzzyMatching
option is set to true
. Also if there is a invisibleId (see the includeInvisibleId option Applanga Commandline Interface) given inside the text
option it will try to resolve the stringPosition by this id. If this fails because of a wrong invisibleId it will fall back to fuzzyMatching if the option is enabled otherwise it will throw an error.
Request example with curl:
# Unix
$ curl 'https://api.applanga.com/v1/api/screenshots?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>' -F 'file=@/full_path_to/screenshot.png' -F 'data={"screenTag": "tag99", "width": 600, "height": 400, "deviceModel": "test device model", "platform": "test platform", "operatingSystem": "test os", "bundleVersion": "test bundle version", "deviceLanguageLong": "en", "stringPositions": [ { "key": "key99", "x": 100, "y": 10, "width": 200, "height": 40 } ]}'
# Windows
$ curl "https://api.applanga.com/v1/api/screenshots?app=<your-app_id>" -H "Authorization: Bearer <your-api_token>" -F "file=@drive:\full_path_to\screenshot.png" -F "data={\"screenTag\": \"tag99\", \"width\": 600, \"height\": 400, \"deviceModel\": \"test device model\", \"platform\": \"test platform\", \"operatingSystem\": \"test os\", \"bundleVersion\": \"test bundle version\", \"deviceLanguageLong\": \"en\", \"stringPositions\": [ { \"key\": \"key99\", \"x\": 100, \"y\": 10, \"width\": 200, \"height\": 40 } ]}"
# HTTP/1.1 200 OK
> {}
Send a GET request to https://api.applanga.com/v1/api/tags?app={app_id}
. The API will identify your App, authenticate the token.
Request example with curl:
# Unix
$ curl 'https://api.applanga.com/v1/api/tags?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>'
# Windows
$ curl "https://api.applanga.com/v1/api/tags?app=<your-app_id>" -H "Authorization: Bearer <your-api_token>"
# HTTP/1.1 200 OK
> [
> {
> "id":"5e2996645a463ed6feabdebc",
> "name":"my_tag_2",
> "entryKeys":["key1","key2"],
> "category":"Web",
> "createdAt":"2020-01-23T12:49:40.376Z",
> "updatedAt":"2020-01-23T17:22:05.276Z"
> },
> {
> "id":"5e2996645a463ed6feabaea",
> "name":"my_tag_1",
> "entryKeys":["key3","key4"],
> "category":"Jira",
> "createdAt":"2020-01-21T12:18:47.371Z",
> "updatedAt":"2020-01-21T17:29:15.274Z"
> },
> ...
> ]
Send a GET request to https://api.applanga.com/v1/api/tags/:tagId?app={app_id}
. The API will identify your App, authenticate the token.
Request example with curl:
# Unix
$ curl 'https://api.applanga.com/v1/api/tags/<tag_id>?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>'
# Windows
$ curl "https://api.applanga.com/v1/api/tags/<tag_id>?app=<your-app_id>" -H "Authorization: Bearer <your-api_token>"
# HTTP/1.1 200 OK
> {
> "id":"5e2996645a463ed6feabdebc",
> "name":"my_tag_2",
> "entryKeys":["key1","key2"],
> "category":"Web",
> "createdAt":"2020-01-23T12:49:40.376Z",
> "updatedAt":"2020-01-23T17:22:05.276Z"
> }
Send a POST request to https://api.applanga.com/v1/api/tags/?app={app_id}
with a json body. The API will identify your App, authenticate the token.
Body example (remember to use Content-Type: application/json
as request header):
{
"name": "my_tag_99",
"category": "ios",
"entryKeys": ["key11", "key12"]
}
Request example with curl:
# Unix
$ curl -X POST 'https://api.applanga.com/v1/api/tags?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>' -H 'Content-Type: application/json' -d '{"name": "my_tag_99", "entryKeys": ["key11","key12"], "category": "ios"}'
# Windows
$ curl -X POST "https://api.applanga.com/v1/api/tags?app=<your-app_id>" -H "Authorization: Bearer <your-api_token>" -H "Content-Type: application/json" -d "{\"name\": \"my_tag_99\", \"entryKeys\": [\"key11\",\"key12\"], \"category\": \"ios\"}"
# HTTP/1.1 201 CREATED
> {
> "id":"5e2886645a463ed6feabdabc",
> "name":"my_tag_99",
> "entryKeys":["key11","key12"],
> "category":"ios",
> "createdAt":"2020-01-24T12:49:40.376Z",
> "updatedAt":"2020-01-24T17:22:05.276Z"
> }
Send a PUT request to https://api.applanga.com/v1/api/tags/:tagId?app={app_id}
with a json body. The API will identify your App, authenticate the token.
Body example (remember to use Content-Type: application/json
as request header):
{
"name": "my_tag_98",
"category": "Android",
"entryKeys": ["key111", "key112"]
}
Request example with curl:
# Unix
$ curl -X PUT 'https://api.applanga.com/v1/api/tags/<tag_id>?app=<your-app_id>' -H 'Authorization: Bearer <api_token>' -H 'Content-Type: application/json' -d '{"name": "my_tag_98", "entryKeys": ["key21","key22"], "category": "OCR"}'
# Windows
$ curl -X PUT "https://api.applanga.com/v1/api/tags/<tag_id>?app=<your-app_id>" -H "Authorization: Bearer <api_token>" -H "Content-Type: application/json" -d "{\"name\": \"my_tag_98\", \"entryKeys\": [\"key21\",\"key22\"], \"category\": \"OCR\"}"
# HTTP/1.1 200 OK
> {
> "id":"5e2886645a463ed6feabdabc",
> "name":"my_tag_98",
> "entryKeys":["key111","key112"],
> "category":"Android",
> "createdAt":"2020-01-26T12:49:40.376Z",
> "updatedAt":"2020-01-26T17:22:05.276Z"
> }
Send a GET request to https://api.applanga.com/v1/api/entryCount?app={app_id}
. The API will identify your App and authenticate the token and return your App translation data.
Request example with curl:
# Unix
$ curl 'https://api.applanga.com/v1/api/entryCount?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>'
# Windows
$ curl "https://api.applanga.com/v1/api/entryCount?app=<your-app_id>" -H "Authorization: Bearer <your-api_token>"
# HTTP/1.1 200 OK
> {
> "en": {
> "accepted": 0,
> "needsAttention": 0,
> "inOrder": 0,
> "new": 88,
> "needsTranslation": 0,
> "needsReview": 0,
> "rejected": 0,
> "all": 88,
> "draft": 2,
> "translated": 85,
> "notTranslated": 0,
> "locked": 3
> },
> "fr": {
> "accepted": 24,
> "needsAttention": 11,
> "inOrder": 2,
> "new": 1,
> "needsTranslation": 0,
> "needsReview": 58,
> "rejected": 3,
> "all": 88,
> "draft": 60,
> "translated": 24,
> "notTranslated": 0,
> "locked": 4
> },
> ...
> }