Languages and translations
Who can use this feature?
An admin on Pro or Plus can create a scoped API key. Reads require settings:read. Language changes require settings.languages:write, and translation edits and resets require settings.translations:write; settings:write grants both. Publishing languages and automatic translation follow the store's plan allowance.
All paths are relative to the Public API base URL. Send X-Api-Key on each request and Content-Type: application/json for writes with a body. Language routes manage which languages exist and are published. Translation routes edit the translated text.
Language operations
All successful calls return 200. Use language codes such as en or ja, not translation document IDs.
| Method | Path | Scope | Request example | Response example |
|---|---|---|---|---|
| GET | /languages | settings:read | No body | {"data":[{"code":"en","status":"published","isDefault":true},{"code":"ja","status":"unpublished","isDefault":false}]} |
| POST | /languages | settings.languages:write | {"code":"ja"} | {"data":{"id":"translation_123","code":"ja"}} |
| PATCH | /languages/{code} | settings.languages:write | {"status":"published"} | {"success":true} |
| DELETE | /languages/{code} | settings.languages:write | No body | {"success":true} |
| PUT | /languages/default | settings.languages:write | {"code":"ja","confirm":true} | {"success":true} |
Adding a language creates it as unpublished. The translation service prepares its content; automatic translation depends on the current plan and allowance. Check GET /languages before adding a code again after an uncertain response.
PATCH accepts only a single status field, with published or unpublished. Extra fields are rejected. Publishing a language does not change which language is the default. Publishing counts against the plan's language limit: when the default and published languages already reach it, the route returns 403 PLAN_LIMIT. A status change is published to the storefront.
curl -X PATCH 'https://app.chatty.net/v1/languages/ja' \
-H 'X-Api-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{"status":"published"}'Change the default or remove a language
Changing the default requires confirm: true. It marks the selected language as default and published, and clears the previous default flag. If the selected language does not exist, the service creates it first. The previous default's publication status follows the store's plan rules.
curl -X PUT 'https://app.chatty.net/v1/languages/default' \
-H 'X-Api-Key: sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{"code":"ja","confirm":true}'You cannot delete the default language. Choose another default first, then delete the old code. Deletion removes that language's saved translation document; it is not the same as unpublishing it.
Edit translation content
| Method | Path | Scope | Request example | Response |
|---|---|---|---|---|
| GET | /translations/{code} | settings:read | No body | 200, translation document |
| PATCH | /translations/{code} | settings.translations:write | {"fields":[{"path":"Show Navigation.Search","value":"Rechercher"}]} | 200 {"success":true} |
| PATCH | /translations/{code}/faq/categories/{id} | settings.translations:write | {"question":"Livraison"} | 200 {"success":true} |
| PATCH | /translations/{code}/faq/questions/{id} | settings.translations:write | {"categoryId":"category_123","question":"Puis-je retourner un article ?","answer":"Oui, sous 30 jours."} | 200 {"success":true} |
| PATCH | /translations/{code}/suggested-faqs/{id} | settings.translations:write | {"question":"...","answer":"..."} | 200 {"success":true} |
| POST | /translations/{code}/reset | settings.translations:write | {"autoTranslate":true} | 200 {"success":true} |
{code} is a language code that already exists; add it first with POST /languages. An unknown code returns 404 NOT_FOUND with Translation not found. Bodies are strict.
GET /translations/{code} returns the stored translations by section. Reading never creates anything:
{
"data": {
"id": "translation_123",
"language": "fr",
"isDefault": false,
"status": "unpublished",
"isAutoTranslate": false,
"Show Navigation": {"Search": "Chercher"},
"Help center": {},
"FAQs": {"category_123": {"question": "Livraison", "questions": [{"questionId": "question_123", "question": "...", "answer": "..."}]}},
"FAQ Suggestions": {"suggestion_123": {"question": "...", "answer": "..."}}
}
}The example is an excerpt; other sections such as FAQ page and Campaign appear too.
Edit fields. PATCH /translations/{code} takes 1–1,000 fields, each with a path and a value. A path must be one of these sections, or a key inside it: Show Navigation, FAQ page, FAQs, Campaign, Help center, Synced Widget Copy, emailReplyHint. Any other path, such as language or isDefault, returns 400 VALIDATION_FAILED with Translation path is not editable. For Show Navigation and Help center you can also send the whole section as an object of strings. Email texts cannot contain links. Changes to the default language also update the widget copy and the Help center.
Edit an FAQ. The category route takes the translated category title as question (up to 10,000 characters). The question route needs categoryId, question and answer (answer up to 100,000 characters). The suggested FAQ route needs question and answer. The category, question or suggestion must already exist in that language, or the route returns 404 NOT_FOUND.
Reset. POST /translations/{code}/reset rebuilds the generated translations of a language. autoTranslate: true also turns on automatic translation for it. Each store can reset 5 times per hour across all languages, keys and MCP; the next call returns 429 RATE_LIMITED.
Automatic translation needs a paid plan and a free auto-translate slot. When you send autoTranslate: true, or the language already uses automatic translation, a free plan returns 403 PLAN_RESTRICTED, and a full allowance returns 403 AUTO_TRANSLATE_LIMIT.
Every write is recorded in the audit log with the calling key.
Errors
Errors use {"error":{"code":"VALIDATION_FAILED","message":"Only status (published or unpublished) can be updated"}}.
| HTTP | Code | Meaning |
|---|---|---|
400 | VALIDATION_FAILED | Missing language code on creation, an invalid publication status, extra fields, or a translation path that cannot be edited. |
400 | MISSING_PARAMS | Default-language change lacks confirm: true. |
400 | CANNOT_DELETE_DEFAULT | Tried to delete the current default. |
400 | INVALID_API_VERSION | Invalid version header. |
401 | UNAUTHENTICATED / INVALID_API_KEY | Missing or invalid API key. |
403 | FORBIDDEN | Missing required scope; legacy unscoped keys are not accepted. |
403 | PLAN_LIMIT | Publishing would exceed the plan's language limit. |
403 | PLAN_RESTRICTED / AUTO_TRANSLATE_LIMIT | Automatic translation needs a paid plan, or no auto-translate slot is left. |
404 | NOT_FOUND | Language, translation, FAQ item or store not found. |
429 | RATE_LIMITED | Shared Public API limit, or 5 resets per hour per store. |
500 | INTERNAL_ERROR | Translation service failed. Inspect the current language list before retrying an uncertain change. |
The MCP tool reference exposes language reads through get_settings_resource, language changes through manage_languages, and translations through manage_translations. With OAuth, manage_translations can only read. Follow that reference for the action, code, and body fields.
Chatty Help Center