Translation Endpoints
Translation is part of All tools. A start needs the
relevant scope and enough credits, and the tool must be available in
/v1/health. Free credits also follow the
free limits. Accepted starts return 202 Accepted.
Translation endpoints create billable asynchronous operations that translate inline text-like content or an existing operation artifact while preserving the input structure. Supported formats are plain text, Markdown, HTML, XML, and JSON.
This endpoint is preview. Preview means the contract may still evolve before stable release.
Shared Access
- Access: Paid plans that include this family, or free credits (guest trial or verified account) within the free limits.
- Operation family: Translation
- Scope:
api:translate:write - Idempotency:
Idempotency-Keyheader required - Sources: inline content or a customer-visible reusable
artifact_id - Callbacks: supported through one-off operation callback fields
Unsupported fields are rejected with validation_failed. Translation endpoints
do not accept raw file uploads, URLs, local paths, file_id,
provider-specific handles or payloads, or arbitrary storage handles.
Translation does not support dry_run.
POST/v1/translate
Creates a translation operation.
Request
Inline source example:
{
"source": {
"type": "inline",
"format": "markdown",
"content": "# Welcome\n\nHello {{name}}, your invoice is ready."
},
"target_language": "de-DE",
"source_language": "en-US",
"style": "idiomatic",
"formality": "default",
"preserve_placeholders": true,
"glossary": [
{
"source": "invoice",
"target": "Rechnung",
"required": true
}
],
"max_output_characters": 20000,
"max_credit_budget": 25
}
Artifact source example:
{
"source": {
"type": "artifact_id",
"id": "art_01JZ7H0A1B2C3D4E5F6G7H8J9K"
},
"target_language": "fr-FR",
"style": "verbatim"
}
Curl example:
curl -X POST https://www.chab.ai/v1/translate \
-H "Authorization: Bearer CHAB_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: translate-001" \
-d '{
"source": {
"type": "inline",
"format": "text",
"content": "Hello {{name}}, your invoice is ready."
},
"target_language": "de-DE",
"preserve_placeholders": true
}'
Fields:
source.type: requiredinlineorartifact_id.source.format: required for inline sources. One oftext,html,xml,markdown, orjson.source.content: required for inline sources. Must be UTF-8 and at most 100,000 characters.source.id: required for artifact sources. The artifact must belong to the same team and API key context, be customer-visible, readable, and unexpired.target_language: required BCP 47-style language tag, such asde-DE.source_language: optional BCP 47-style language tag.style: optionalidiomaticorverbatim. Defaults toidiomatic.formality: optionaldefault,formal, orinformal. Defaults todefault.preserve_placeholders: optional boolean. Defaults totrue.glossary: optional array of source/target term objects. Terms can setrequiredandcase_sensitive.excluded_json_paths: optional JSON paths to leave untranslated. Only valid for JSON sources.max_output_characters: optional inline result size threshold. Larger translations are stored as a protected artifact instead of being rejected.max_credit_budget: optional per-request budget ceiling.callback_url,callback_secret,callback_events, andcallback_notify_on_expiration: optional one-off operation callback fields.
Supported Structure Preservation
Chab keeps the original structure outside the translated text units where possible:
| Format | Preserved structure |
|---|---|
text |
Line and blank-line layout. |
markdown |
Headings, lists, quotes, fenced code blocks, inline code, tables, images, links, and front matter structure. |
html |
Tag order, nesting, attributes, and approved text-bearing attributes. |
xml |
Element names, namespaces, attributes, order, and text node placement. |
json |
Object keys, key order, array length, scalar types, and excluded paths. |
When preserve_placeholders is true, placeholders such as {{name}},
{name}, %s, :name, and <%= value %> must remain intact.
Async Response
Live requests return 202 Accepted with the standard operation envelope:
{
"operation": {
"id": "op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
"status": "queued",
"operation_key": "translate.text_or_document",
"family": "translate",
"status_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
"result_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/result",
"estimated_credits": 5,
"result_available": false,
"warnings": []
},
"meta": {
"request_id": "req_123",
"credits": {
"estimated": 5,
"reserved": 5,
"currency": "credit"
}
}
}
Poll the operation status URL until it reaches a terminal state, or fetch the
result URL after result_available becomes true.
Result
Small translations return translated_content inline:
{
"data": {
"result": {
"format": "markdown",
"source_language": {
"requested": "en-US",
"detected": null
},
"target_language": "de-DE",
"translated_content": "# Willkommen\n\nHallo {{name}}, deine Rechnung ist bereit.",
"artifact": null,
"validation": {
"structure_preserved": true,
"placeholders_preserved": true,
"required_glossary_terms_satisfied": true
},
"glossary": {
"term_count": 1,
"required_count": 1,
"preferred_count": 0,
"required_matched": 1,
"preferred_matched": 0,
"preferred_missing": 0
},
"usage": {
"pricing_class": "translation-standard",
"input_tokens": 42,
"output_tokens": 24,
"repair_count": 0,
"pass_count": 2,
"charged_credits": 5,
"currency": "credit"
},
"language": {
"source": "en-US",
"target": "de-DE",
"style": "idiomatic",
"formality": "default"
},
"warnings": []
},
"artifacts": [],
"warnings": [],
"result_expires_at": "2026-07-17T12:00:05+00:00"
},
"meta": {
"request_id": "req_123"
}
}
If the translated content exceeds max_output_characters, the result omits
translated_content, stores the full output as a protected artifact with role
translated_output, and emits result_truncated:
{
"data": {
"result": {
"format": "markdown",
"source_language": {
"requested": "en-US",
"detected": null
},
"target_language": "de-DE",
"artifact": {
"role": "translated_output",
"type": "markdown",
"mime_type": "text/markdown",
"filename": "translation.md",
"byte_size": 18420,
"checksum": "sha256:example"
},
"validation": {
"structure_preserved": true,
"placeholders_preserved": true,
"required_glossary_terms_satisfied": true
},
"glossary": {
"term_count": 0,
"required_count": 0,
"preferred_count": 0,
"required_matched": 0,
"preferred_matched": 0,
"preferred_missing": 0
},
"usage": {
"pricing_class": "translation-standard",
"input_tokens": 2100,
"output_tokens": 1600,
"repair_count": 0,
"pass_count": 2,
"charged_credits": 18,
"currency": "credit"
},
"language": {
"source": "en-US",
"target": "de-DE",
"style": "idiomatic",
"formality": "default"
},
"warnings": [
{
"code": "result_truncated",
"message": "Translated output exceeded max_output_characters and was stored as an artifact.",
"field": "translated_content",
"severity": "info"
}
]
},
"artifacts": [
{
"id": "art_01JZ7H0A1B2C3D4E5F6G7H8J9K",
"type": "markdown",
"role": "translated_output",
"mime_type": "text/markdown",
"byte_size": 18420,
"checksum": "sha256:example",
"filename": "translation.md",
"metadata_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/artifacts/art_01JZ7H0A1B2C3D4E5F6G7H8J9K",
"download_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/artifacts/art_01JZ7H0A1B2C3D4E5F6G7H8J9K/download",
"expires_at": "2026-07-17T12:00:05+00:00"
}
],
"warnings": [
{
"code": "result_truncated",
"message": "Translated output exceeded max_output_characters and was stored as an artifact.",
"field": "translated_content",
"severity": "info"
}
]
}
}
Artifact MIME types match the translation format:
| Format | MIME type | Extension |
|---|---|---|
text |
text/plain |
.txt |
markdown |
text/markdown |
.md |
html |
text/html |
.html |
xml |
application/xml |
.xml |
json |
application/json |
.json |
Download translated artifacts through the artifact download_url before
expires_at. Artifact metadata and downloads require bearer authentication.
Pricing
Translation uses dynamic token pricing under the public pricing class
translation-standard:
max(5, ceil(input_tokens * 2 / 1000 + output_tokens * 8 / 1000))
The initial hold is a deterministic worst-case estimate. It includes source
tokens, prompt and response overhead, glossary and placeholder instructions,
the selected style, both passes for idiomatic, and up to two repair attempts.
verbatim uses one main translation pass. max_output_characters affects only
inline-versus-artifact placement; it is not a token cap.
Settlement uses actual input and output usage across translation, refinement,
and repair attempts, capped at the reserved hold. Use max_credit_budget to
deny a request before operation rows or credit holds when the estimate is
higher than the supplied budget.
Unsupported format, source-size, validation, artifact-source, scope, plan, budget, insufficient-credit, and provider-readiness denials before provider work are not charged. Validation failures after translation work starts can charge the actual incurred usage, capped at the hold.
See Credits and Billing.
Warnings
| Code | Meaning |
|---|---|
result_truncated |
The translated output exceeded max_output_characters and was stored as translated_output. |
glossary_preferred_missed |
One or more preferred glossary targets were not present in the translated output. Required glossary misses fail instead. |
Source State Errors
Artifact sources use the shared artifact-input behavior. Missing artifacts,
cross-team artifacts, artifacts the key cannot read, and artifacts whose stored
bytes are no longer readable return not_found without disclosing which
condition applied.
| Code | HTTP | Retry | Chargeable | What to do |
|---|---|---|---|---|
not_found |
404 | No | No | Check the artifact id and make sure it belongs to the same team and token context. |
artifact_expired |
410 | No | No | Use a non-expired artifact. |
Translation Errors
| Code | HTTP | Retry | Chargeable | What to do |
|---|---|---|---|---|
unsupported_format |
422 | No | No | Use text, html, xml, markdown, or json, or choose a supported artifact. |
source_too_large |
422 | No | No | Reduce the resolved source content to 100,000 characters or less. |
structure_validation_failed |
422 | No | Yes, after work starts | Reduce source complexity or split the document into smaller translations. |
placeholder_integrity_failed |
422 | No | Yes, after work starts | Check placeholders in the source and retry with a smaller or simpler source. |
repair_exhausted |
422 | No | Yes, after work starts | Split the source, simplify glossary or placeholder requirements, then start a new operation. |
artifact_creation_failed can also occur if Chab cannot persist a translated
artifact. In that case the hold is released because the output is not available.
Callbacks
Callbacks use the standard operation callback contract. Terminal callback
payloads use the same operation shape as polling, including operation.status,
operation.public_error_code, settlement facts when available, warnings, and
artifact references when the result succeeded. Use the operation result URL to
read the retained translation result or download translated artifacts.