docsTranslation APIInDesign (IDML)

    🖋️ InDesign (IDML)

    Bluente translates Adobe InDesign documents natively when you send them as IDML (InDesign Markup Language, .idml). The translated result is an editable IDML package that you open in InDesign — not a print-ready PDF.


    📋 Workflow

    IDML uses the same endpoints as every other file type:

    1. Upload File — upload the .idml file with POST /upload.
    2. Get Translation Status — poll GET /check until the status is SERVICE_PROCESSED. If the package is invalid, the status becomes ERROR instead.
    3. Translate File — start the translation with POST /translate. Leave out the options listed below.
    4. Download File — when the status is READY, download the result with GET /download. Omit to_type or set to_type=idml.

    📤 Preparing the File

    • Export IDML from InDesign (File → Export… → InDesign Markup (IDML)) and upload the .idml file. Do not upload .indd files.
    • IDML is accepted by POST /upload. It is not listed by the Get Supported File Types API yet, so don’t use that list to decide whether to send IDML.

    🚫 Options Not Supported for IDML

    IDML translation keeps the authored InDesign layout and translates the native text. The options below don’t apply to it. If you send any of them, POST /translate returns code: 40 (invalid parameters) and the translation does not start.

    OptionWhere it is sentRule for IDML
    to_typeRequest bodyMust be empty or "idml". PDF or INDD output is not available.
    page_rangeRequest bodyNot supported — the whole document is always translated.
    scanned / scanned_optionQuery / request bodyMust be 0 or omitted.
    translate_imageQuery / request bodyNot supported.
    table_layout_enhancement / is_use_table_layout_enhancementQuery / request bodyNot supported.
    only_extract / is_only_extractQuery / request bodyNot supported.
    bilingual, vertical_bilingual / is_use_bilingual, is_vertical_bilingualQuery / request bodyNot supported.
    font_name, custom fontsRequest bodyNot supported. Fonts come from the original document.

    Glossary options (glossary, custom_glossary, namespace) and meta_data work as usual.


    💡 Example

    # 1. Upload
    curl -X POST "https://api.bluente.com/api/20250924/blu_translate/upload?engine=3" \
         -H "Authorization: Bearer $BLUENTE_API_KEY" \
         -F "file=@/path/to/brochure.idml"
     
    # 2. Translate (after /check returns SERVICE_PROCESSED)
    curl -X POST "https://api.bluente.com/api/20250924/blu_translate/translate?engine=3" \
         -H "Authorization: Bearer $BLUENTE_API_KEY" \
         -H "Content-Type: application/json" \
         -d '{
               "id": 1,
               "action": "start",
               "from": "en",
               "to": "zh"
             }'
     
    # 3. Download (after /check returns READY)
    curl -X GET "https://api.bluente.com/api/20250924/blu_translate/download?id=1&to_type=idml" \
         -H "Authorization: Bearer $BLUENTE_API_KEY" \
         -o translated_brochure.idml

    or

    const formData = new FormData();
    formData.append("file", fileInput.files[0]); // brochure.idml
     
    const upload = await fetch("https://api.bluente.com/api/20250924/blu_translate/upload?engine=3", {
      method: "POST",
      headers: {
        "Authorization": "Bearer $BLUENTE_API_KEY"
      },
      body: formData
    }).then(res => res.json());
     
    // Poll /check until status is SERVICE_PROCESSED, then:
    await fetch("https://api.bluente.com/api/20250924/blu_translate/translate?engine=3", {
      method: "POST",
      headers: {
        "Authorization": "Bearer $BLUENTE_API_KEY"
      },
      body: JSON.stringify({
        id: upload.data.id,
        action: "start",
        from: "en",
        to: "zh"
      })
    });
     
    // Poll /check until status is READY, then:
    const file = await fetch(`https://api.bluente.com/api/20250924/blu_translate/download?id=${upload.data.id}&to_type=idml`, {
      method: "GET",
      headers: {
        "Authorization": "Bearer $BLUENTE_API_KEY"
      }
    }).then(res => res.blob());

    ❌ Error Response Example

    {
      "message": "IDML translation supports the complete document, not page selections",
      "code": 40
    }

    See Error Codes for all codes.


    💳 Billing

    • IDML is billed for the whole document. Partial translation and watermarked previews are not available for IDML.
    • If the account cannot pay for the complete document, the translation does not start: code: 70 when credits are insufficient or expired, or code: 40 when the account would only get a partial preview.

    📌 Notes

    • The output is an editable IDML package. Open it in InDesign and review it before you export or print.
    • Translated text is usually longer or shorter than the source. Check every spread for overset (overflowing) text and adjust frames where needed.
    • Fonts and linked assets are not bundled. IDML stores fonts and links (images, placed files) by reference only. Install the document’s fonts and relink assets on the machine that opens the translated file.
    • If the original font cannot display the target language, Bluente applies a fallback font to that text. Check fonts in InDesign (Type → Find/Replace Font…) before final output.