Any language via REST API

No SDK for your stack yet? The same translation API the widget and the Apps SDK use is plain HTTPS + JSON. If your language can send a POST request, it can translate with Transable — Python, Go, Rust, Java, PHP, shell scripts, anything.

Authentication

Every request is authenticated with a project API key (tk_live_…) — create one on your project page. Pass it either in the JSON body as apiKey, as a Authorization: Bearer header, or as an X-Api-Key header. There are no cookies or OAuth flows.

Translate a batch of texts

POST /api/v1/translate/batch translates up to 500 texts per call into one target language. The source language is detected automatically.

curl https://transable.to/api/v1/translate/batch \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer tk_live_yourKeyHere" \
  -d '{
    "texts": ["Welcome back!", "Sign out"],
    "targetLanguage": "de"
  }'

The response echoes each source text with its translation:

{
  "translations": [
    { "sourceText": "Welcome back!", "translatedText": "Willkommen zurück!", "served": "ai" },
    { "sourceText": "Sign out",      "translatedText": "Abmelden",           "served": "cache" }
  ]
}

The served field tells you how each text was produced:

  • ai — freshly translated (counts against your AI character quota);
  • cache — served from the server phrase cache (free);
  • original — returned untranslated: the echo path (target = source), the budget governor's cache-only mode, or a pass-through. This lets your client distinguish "refused by budget" from "the translation happens to equal the source".

List enabled languages

GET /api/v1/translate/languages returns your project's source language and every enabled target language (names, native names, flags) — ideal for building your own language picker:

curl "https://transable.to/api/v1/translate/languages?apiKey=tk_live_yourKeyHere"
{
  "sourceLanguage": "en",
  "languages": [
    { "code": "de", "name": "German",  "nativeName": "Deutsch",  "flag": "🇩🇪" },
    { "code": "es", "name": "Spanish", "nativeName": "Español", "flag": "🇪🇸" }
  ]
}

Size and rate limits

413 means one request was too big — the batch's total characters exceeded your plan's per-request cap (the response includes the exact limit), so split the batch and retry. 429 means you are sending requests too fast or hit a quota — back off for the number of seconds in the Retry-After header and resend; nothing is lost.

Protocol expectations

A well-behaved client follows the same rules the official SDK does:

  • batch aggressively — up to 500 texts per /batch call instead of one request per string;
  • honor Retry-After on 429 and pause the queue instead of hammering;
  • cache translations client-side and fall back to the original text on any error.

The Avalonia SDK's limits and error behavior documents the reference behavior these expectations come from.

Other status codes

  • 400 — malformed request (missing texts / targetLanguage, or more than 500 texts);
  • 401 — invalid or revoked API key;
  • 402 — no active subscription on the account;
  • 403 — target language not enabled for the project, or the request origin is not allowed;
  • 502 — transient provider failure: keep the original text and retry later.

Building for Avalonia or WPF instead? The Apps SDK (Avalonia, WPF) handles all of the above for you — batching, caching, retries, and offline startup.