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-Key header 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: required inline or artifact_id.
  • source.format: required for inline sources. One of text, html, xml, markdown, or json.
  • 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 as de-DE.
  • source_language: optional BCP 47-style language tag.
  • style: optional idiomatic or verbatim. Defaults to idiomatic.
  • formality: optional default, formal, or informal. Defaults to default.
  • preserve_placeholders: optional boolean. Defaults to true.
  • glossary: optional array of source/target term objects. Terms can set required and case_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, and callback_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.