Applanga API


Version: 1.0.3

Website: https://www.applanga.com


Table of Contents

  1. Requirements & Usage
  2. Authorization
  3. Payload Compression
  4. Requesting translation data
  5. Posting translation data
  6. JSON Schema for API write access
  7. Requesting screenshots
  8. Uploading screenshot
  9. Requesting a list of tags
  10. Requesting a tag by id
  11. Creating a new tag
  12. Updating a tag by id
  13. Requesting project entry counts
  14. Requesting Branches
  15. Create sibling project

Requirements & Usage

  1. To make requests to the Applanga API you first need to create a Project in the Applanga Dashboard.

  2. 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.

Authorization

  1. 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

  2. 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.

  3. If you are using a project with Branching and want to target a specific branch you also need to provide the branch_id through the branch parameter. You can get the branch_id either in the Settings of your application or request it via an api route (see Requesting Branches). Example: https://api.applanga.com/v1/api?app={app_id}&branch={branch_id}

  4. 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.

Payload Compression

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.

Requesting translation data

  1. 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.

Note: If you are using a Branching Project and want to request a specific branch you also need to provide the branch_id as a parameter https://api.applanga.com/v1/api?app={app_id}&branch={branch_id}. You can get the branch_id either in the Settings of your application or request it via an api route (see Requesting Branches or for more information about branching have a look at our Branching Documentation). All availible Api features can be extended with the "branch" parameter and will perform the requested action on the specified branch. If there is no branch parameter in the request, the action is performed on the "main" branch.

  1. 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".

  2. 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.

  3. 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].

  4. 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.

  5. It is also possible to include additional data or removing data from the response by adding additional query parameters.

  • includeSrc=true Adds src property which describes a file origin for the specific string in that specific language. These file sources can originate from imported .xliff files or from data writte through this API. (default=false)
  • includeStatus=true Adds status property which describes the current state of the translation (default=false)
  • includeComment=true Adds comment property of the translation if a comment was made (default=false)
  • includeLockInfo=true Adds locked property to the translation, to indicate if it is locked or not (default=false)
  • includeDescription=true Adds description property of the translation keys in the base language (default=false)
  • includeMeta=true Adds meta (metadata) property of the translation keys in the base language. Empty metadata values are not included (default=false)
  • includeMetaForAllLanguages=true Adds meta (metadata) property of the translation keys in all languages. Empty metadata values are not included (default=false)
  • includeDraft=true Adds d(draft) property (default=true)
  • includeValue=true Adds v(value) property (default=true)
  • keepEmptyDataEntries=true By default all groups and entries that do not have values get deleted from response (default=false)
  • includeUpdateDate=true Adds updatedAt property (default=false)
  • includeUserId=true Adds userId property (default=false)
  • includeLanguageId=true Adds languageId property under each group (default=false)
  • includeGroupId=true Adds groupId property under each group (default=false)
  • includeStatusDescription=true When this parameter is set to true, the response body includes a property 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

Posting translation data

  1. 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.

Note: If you are using a Branching Project and want to request a specific branch you also need to provide the branch_id as a parameter https://api.applanga.com/v1/api?app={app_id}&branch={branch_id}. You can get the branch_id either in the Settings of your application or request it via an api route (see Requesting Branches or for more information on Branching have a look at our Branching Documentation).

  1. 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 changes on translation entries if the draft property (d) or value (v) are empty or not provided in the request. 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.

  2. 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"
        }
    }
    
  3. 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"
                        }
                    }
                }
            }
        }
    }
    

    Note The Metadata Field Name can not start with the word Applanga because this prefix is restricted for internal use

  4. 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"
    >    ]
    > }
    
  5. Locking & Unlocking Translation Entries

For GET requests the locked property indicates if a translation entry is locked.

In POST requests you can use the locked property to change the locked state of a translation as shown in the following example POST body.

In the options you need to set skipLockedTranslations to false to make sure already locked translations are not skipped and skipEmpty needs to be set to false as well to be able to send translations without the requirement to provide a draft d or value v property in the request.

Also note locking via API only works on per language and you can not set a key to be locked across all languages as you can do on the dashboard. For more details on that see the Locking-Entries documentation

    {
        "options":{
            "skipEmpty": false,
            "skipLockedTranslations": false
        },
        "data":{
            "en":{
                "main":{
                    "entries":{
                        "key1":{
                            "locked": true
                        },
                        "key2":{
                            "locked": false
                        },
                    }
                }
            }
        }
    }

JSON Schema for API write access

  1. This describes the format of the json body expected for an API POST request

  2. 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",
                                                "additionalProperties":false,
                                                "properties":{
                                                    "d" : {
                                                        "type": "string"
                                                    },
                                                    "v" : {
                                                        "type": "string"
                                                    },
                                                    "locked" : {
                                                        "type": "boolean"
                                                    },
                                                    "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"
            }
        }
    }
    

Requesting screenshots

  1. 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.

  2. 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,
    >             "sha1": "907d14fb3af2b0d4f18c2d46abe8aedce17367bd"
    >             "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.

    Screenshot Hashes

    If you want to save time and bandwidth you can reduce the amount of screenshot uploads by checking the sha1 hash property of an already uploaded screenshot to see if your local file is different and only upload if thats the case. But be aware that the sha1 hash is only available for screenshots uploaded after 15. Nov. 2023.

    The sha1 hash is stored in hex format and you could generate the hash locally in nodejs with the following code:

    const Crypto = require('crypto');
    const fs = require('fs');
    
    const hashSum = Crypto.createHash('sha1');
    const buffer = fs.readFileSync('/path/to/your/screenshot');
    hashSum.update(buffer);
    
    const hex = hashSum.digest('hex');
    return hex;
    

Uploading screenshot

  1. 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.

  2. 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.

  3. 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
    
    > {}
    

Requesting a list of tags

  1. Send a GET request to https://api.applanga.com/v1/api/tags?app={app_id}. The API will identify your App, authenticate the token.

  2. 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"
    >   },
    >   ...
    > ]
    

Requesting a tag by id

  1. 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.

  2. 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"
    > }
    

Creating a new tag

  1. 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.

  2. Body example (remember to use Content-Type: application/json as request header):

    {
        "name": "my_tag_99",
        "category": "ios",
        "entryKeys": ["key11", "key12"]
    }
    
  3. 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"
    > }
    

Updating a tag by id

  1. 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.

  2. Body example (remember to use Content-Type: application/json as request header):

    {
        "name": "my_tag_98",
        "category": "Android",
        "entryKeys": ["key111", "key112"]
    }
    
  3. 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"
    > }
    

Requesting project entry counts

  1. 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.

  2. 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
    >     },
    >     ...
    > }
    

Request Branch Info

To learn more about branching please have a look at our Branching Documentation)

  1. Send a GET request to https://api.applanga.com/v1/api/branches?app={app_id}. The API will identify your App and authenticate the token and return the branch details.

  2. Request example with curl:

    # Unix
    $ curl 'https://api.applanga.com/v1/api/branches?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>'
    
    #Windows
    $ curl "https://api.applanga.com/v1/api/branches?app=<your-app_id>" -H "Authorization: Bearer <your-api_token>"
    
    # HTTP/1.1 200 OK
    > {
    >     "branches": [
    >       {
    >           "name": "main",
    >           "_id": "<main-branch-id>"
    >       },
    >       {
    >           "name": "development",
    >           "_id": "<development-branch-id>"
    >       }
    >     ],
    >     "currentBranch": "<current-branch-id>"
    > }
    

All availible API features can be extended with the "branch" parameter and will perform the same thing just on the specified. If no branch is specified the original Branch will be taken.

Create sibling project

Create a new project and based of another existing project. This allows you to copy settings, attributes and configs from the existing project into the new one.

  1. Send a POST request to https://api.applanga.com/v1/api/createSiblingProject?app={app_id}. The API will identify your Project and authenticate the token and create a new project that is a copy of the existing project.

  2. Request example with curl:

    # Unix
    $ curl 'https://api.applanga.com/v1/api/createSiblingProject?app=<your-app_id>' -H 'Authorization: Bearer <your-api_token>'
    
    # Windows
    $ curl "https://api.applanga.com/v1/api/createSiblingProject?app=<your-app_id>" -H "Authorization: Bearer <your-api_token>"
    
    # HTTP/1.1 200 OK
    
    > {
    >     "projectName":"Sibling",
    >     "identicalLanguages":false,
    >     "identicalGroups":false,
    >     "identicalProjectSettings":false,
    >     "identicalBranches":false
    > }
    

    A new project named Sibling will be created with data from the project whose token was supplied in the request

  3. The projectName is required and must be set in the request body. It is the name that will be set for the new project. The name of the project must be unique for the team which the request project belongs to. If the projectName is already in use by another project, the api will return an error response.

  4. By default an empty project is created when the request is completed with only a default language set for the new project. However it is possible to copy some more data, like the project settings, groups, languages, webhooks and other project settings. To enable this any of the following options which are false by default should be set to true in the request body.

  • identicalLanguages=true Creates all the languages in the requested project in the new project (default=false)
  • identicalGroups=true Creates all the groups in the requested project in the new project (default=false)
  • identicalProjectSettings=true Applies all the settings in the requested project in the new project (default=false)
  • identicalBranches=true Creates all the branches in the requested project in the new project. Onl applicable if the requested project is a branching project. (default=false)