Full API reference: developer.universally.com carries the live specification for both the Translator API and the Platform API, with every field, status code and response example. This page covers what is worth knowing around it.
Send an array of strings, get a map of source text to translation. Use this when you have text rather than a page: an app interface, a headless CMS payload, email copy, or push notifications.
Endpoint
POST https://translator.universally.com/v1/translate/strings
X-API-Key: your_api_key_here
Content-Type: application/json
Request
{
"strings": ["Add to cart", "Out of stock", "Free shipping over $50"],
"targetLanguage": "de",
"fresh": false
}
| Field | Required | Notes |
|---|---|---|
strings |
yes | Between 1 and 500 entries. Each must be non-empty. |
targetLanguage |
yes | A language code enabled on the project |
fresh |
no | true bypasses stored translations and translates again. Defaults to false. |
Note there is no sourceUrl here, unlike Translate HTML. Strings are not tied to a page.
Response
{
"success": true,
"data": {
"translations": {
"Add to cart": "In den Warenkorb",
"Out of stock": "Nicht auf Lager",
"Free shipping over $50": "Kostenloser Versand ab 50 $"
},
"metadata": {
"sourceLanguage": "en",
"targetLanguage": "de",
"stringsReceived": 3,
"stringsTranslated": 3,
"limitReached": false,
"skippedStrings": 0
}
},
"code": "DATA_FETCHED"
}
translations is keyed by your original string, so you can look each one up without tracking array order.
Handle missing keys
A string that was not translated is left out of translations entirely. Look up every key with a fallback to your own text:
const out = strings.map((s) => data.translations[s] ?? s);
Three things cause a key to be missing:
- Nothing to translate. A bare number, a URL, an email address, a single character.
- The word total is used up. The workspace was already at or over its limit when the request arrived, which the response reports as
limitReached: truewith askippedStringscount. - A transient failure translating that batch.
Read metadata for the shape of what happened: stringsTranslated below stringsReceived means some are absent.
There is one special case that behaves differently: if nothing in the request was translatable at all, every input is echoed back unchanged. Do not build on that, since it does not apply as soon as one string is translatable.
Deduplication
Repeated strings in one request are translated once. Sending the same label fifty times costs one translation, so there is no need to deduplicate before calling.
Limits
500 strings per request. Over that fails validation. Split larger sets across requests. The 5 MB body limit applies here too. See API errors and limits.
Glossary rules apply
Glossary rules are applied to strings the same way as to pages, so a term you always or never translate behaves consistently across both endpoints. See Glossary rules.
When to use fresh
Leave it false. Stored translations are returned instantly and cost nothing.
fresh: true translates the string again and returns the new text without storing it, so it is a preview rather than a way to change what is served. The next ordinary request for that string still returns the previously stored translation. Because nothing is stored, a fresh call also does not count against your word total.
To change what is served, save the new wording on the Translations screen. See Edit translations manually.