Sign in

API

REST API for text and document translation. Create a key in your dashboard.

Authentication

Pass your key as a bearer token (or x-api-key header).

headers.http
HTTP
Authorization: Bearer wsk_xxx# …or, equivalently:x-api-key: wsk_xxx

Translate text

POST/api/v1/translate
curl -X POST https://translate.baobabtech.app/api/v1/translate \  -H "Authorization: Bearer wsk_xxx" \  -H "Content-Type: application/json" \  -d '{    "source": "en",    "target": "fr",    "text": "Clean water saves lives.",    "domain": "wash"  }'
response.json
JSON
{  "translation": "...",  "source": "en",  "target": "fr",  "domain": "wash",  "model": "...",  "ragApplied": true,  "characters": 24}

domain defaults to wash. Max 50,000 characters per request. Optional reasoning_effort (off · low · medium · high) defaults to off — translation needs no reasoning.

Batch translation

Send an array in text to translate up to 100 strings in one call. Translations come back in translations, aligned to input order. A batch counts as ONE request against the rate limit, so a job of hundreds of short strings costs a handful of requests instead of hundreds. Identical strings are translated once and billed once.

curl -X POST https://translate.baobabtech.app/api/v1/translate \  -H "Authorization: Bearer wsk_xxx" \  -H "Content-Type: application/json" \  -d '{    "source": "en",    "target": "fr",    "domain": "wash",    "text": [      "Clean water saves lives.",      "Hygiene promotion",      "Household water treatment and safe storage"    ]  }'# → { "translations": ["...", "...", "..."], "items": 3, "characters": 74, ... }
response.json
JSON
{  "translations": ["...", "...", "..."],  "items": 3,  "source": "en",  "target": "fr",  "domain": "wash",  "format": "text",  "model": "...",  "characters": 74}

Translating HTML

Set format to html for CMS field values. Markup is never sent to the model: only text nodes are translated and written back into the original document, so tables, images, iframes, links, classes and data- attributes come back untouched. script and style are passed through verbatim and never translated. Characters are billed on visible text only.

Translate a document (.docx, .pptx, .xlsx, .pdf)

Three steps: request an upload URL, upload the file, start the job, then poll.

# 1. Create the job → returns a presigned upload URLcurl -X POST https://translate.baobabtech.app/api/v1/documents \  -H "Authorization: Bearer wsk_xxx" \  -H "Content-Type: application/json" \  -d '{ "filename": "report.docx", "source": "en", "target": "fr", "domain": "wash" }'# → { "jobId": "...", "uploadUrl": "https://...", "method": "PUT", "contentType": "..." }
# 2. Upload the file straight to the presigned URLcurl -X PUT "<uploadUrl>" \  -H "Content-Type: <contentType>" \  --data-binary @report.docx
# 3. Start processingcurl -X POST https://translate.baobabtech.app/api/v1/documents/<jobId>/start \  -H "Authorization: Bearer wsk_xxx"# → { "jobId": "...", "status": "processing" }
# 4. Poll until done, then downloadcurl https://translate.baobabtech.app/api/v1/documents/<jobId> \  -H "Authorization: Bearer wsk_xxx"# → { "status": "done", "downloadUrl": "https://...", "segmentCount": 120 }

Discovery

GET /api/v1/help returns endpoints, limits and capabilities as JSON. It is public, so an integration can self-configure and check connectivity before a key is set.

# All three endpoints are public — no API key required.curl https://translate.baobabtech.app/api/v1/languages# → { "languages": [ { "code": "fr", "name": "French", "script": "Latn", "rtl": false } ] }
curl https://translate.baobabtech.app/api/v1/domains# → { "domains": [ { "slug": "wash", "name": "WASH", "description": "..." } ] }
# Endpoints, limits and capabilities, for integrations that self-configure.curl https://translate.baobabtech.app/api/v1/help# → { "endpoints": { ... }, "formats": ["text", "html"], "languages": ["en", "fr", ...] }

Rate limits & quota

Each key has a per-minute request limit and a monthly character quota (by tier). When exceeded:

  • 429 with Retry-After — rate limit
  • 402 quota_exceeded — monthly character quota reached
  • 401 — missing/invalid key
error.json
JSON
{ "error": { "code": "rate_limited", "message": "..." } }