Skip to contentSkip to content

HTTP Translation Endpoints

Use this page when a script, extension, or third-party application needs to submit manga images to the Manga Translator server for translation. It documents the endpoints under /translate that submit translation tasks, the request and response formats, and the task status while queued and running. It does not repeat the full streaming-frame protocol (see Streaming protocol), the session and permission error conventions (see Authentication and errors), or the auxiliary export/import/colorize/upscale/inpaint endpoints (see Batch, export, and import process). For the Web UI entry points, see Upload, configure, and translate.

Endpoint scope

  • This guide covers the endpoints that submit a translation task and return a result: POST /translate/json, /bytes, /image and their /stream variants, the /with-form/* form variants, /batch/json, /batch/images, and POST /translate/queue-size.
  • manga_translator/server/routes/translation.py registers 31 /translate route declarations in total; the export (/export/*), import (/import/*), process (/upscale, /colorize, /inpaint), and /complete endpoints belong to other pages.
  • Except for queue-size, every translation endpoint calls verify_translation_auth() inside the route: a missing or invalid X-Session-Token returns 401, missing translator/OCR/colorizer/renderer permission returns 403, and parameters disabled for the user or group are overridden with admin defaults before execution.
  • Single and batch requests share one global translator instance and thread pool; models are reused between requests. Server-side translation requests force cli.use_gpu=False and disable desktop-only modes such as replace translation and template alignment.

Endpoint inventory

Single-translation endpoints

Method and pathRequestResponseWorkflow
POST /translate/jsonJSON: TranslateRequestJSON TranslationResponsesave_json
POST /translate/bytesJSON: TranslateRequestCustom byte stream (see Custom byte format)save_json
POST /translate/imageJSON: TranslateRequestPNG StreamingResponsenormal
POST /translate/with-form/jsonmultipart/form-data: image file + config JSON stringJSON TranslationResponsesave_json
POST /translate/with-form/bytesSame as aboveCustom byte streamsave_json
POST /translate/with-form/imageSame as abovePNG StreamingResponsenormal

The JSON variants encode the whole image as a data URI with the data:image/...;base64, prefix in the image field; the form variants upload the file. Both entries accept the same config: a Pydantic Config object in the JSON variants, and a JSON string validated by parse_config() in the form variants.

Streaming translation endpoints

Method and pathRequestResponse
POST /translate/json/streamJSON: TranslateRequestStreaming frames whose result payload is JSON
POST /translate/bytes/streamJSON: TranslateRequestStreaming frames whose result payload is custom bytes
POST /translate/image/streamJSON: TranslateRequestStreaming frames whose result payload is PNG
POST /translate/with-form/json/streamForm: image + configStreaming frames whose result payload is JSON
POST /translate/with-form/bytes/streamForm: image + configStreaming frames whose result payload is custom bytes
POST /translate/with-form/image/streamForm: image + config + user_env_varsStreaming frames whose result payload is PNG (generic mode, suitable for API calls and scripts)
POST /translate/with-form/image/stream/webForm: image + config + user_env_varsStreaming frames whose result payload is PNG (Web-frontend optimized mode)

Streaming endpoints go through while_streaming(), which registers the active task, emits queueing and stage progress, runs the translation, and finally produces result frames with transform_to_json / transform_to_bytes / transform_to_image. /image/stream/web sets the config flag _web_frontend_optimized to true; transform_to_image() returns a 1×1 placeholder PNG when ctx.use_placeholder is set so the response is faster, while the final image is still written to history.

Batch and queue endpoints

Method and pathRequestResponse
POST /translate/batch/jsonJSON: BatchTranslateRequestlist[TranslationResponse]
POST /translate/batch/imagesJSON: BatchTranslateRequestZIP byte stream with the X-Content-Type: application/zip response header
POST /translate/queue-sizeNo bodyJSON integer

POST /translate/batch/images returns 400 when no image is provided; each result uses config.cli.format or the original filename to decide the output format and extension. POST /translate/queue-size returns the length of the module-level task_queue.queue; the active translation path controls concurrency with the translation semaphore (task_manager.translation_semaphore), so this endpoint is a read-only snapshot of the legacy queue structure and does not represent the number of semaphore waiters.

Submitting tasks in the Web UI

The Web frontend (static/index.html + static/script.js) is the main consumer of these endpoints. The workflow dropdown at the top of the page decides which endpoint the request uses; multi-image “Normal Translation” goes to /translate/batch/images (images as data URIs in a JSON body), while a single image or a special workflow goes to the corresponding /translate/* form endpoint.

Request and response contract

Single request TranslateRequest

FieldTypeDescription
imagebytes or strImage bytes from a form upload, or a data URI with the data:image/...;base64, prefix
configConfigFull translation configuration (Pydantic); defaults to Config()

to_pil_image() accepts only these two input kinds; anything else (such as a bare base64 string or a file path) returns 422 with “Invalid image data” or a data-URI hint.

Batch request BatchTranslateRequest

FieldTypeDefaultDescription
imageslist[bytes | str]requiredEach image as bytes or a data URI
configdict or Config{}Configuration; a dict is converted with parse_config()
batch_sizeint4Number of images processed per batch
filenameslist[str][]Original filenames used for output naming and history

Response TranslationResponse

FieldTypeDescription
regionslist[Translation]Text regions in reading order
original_width / original_heightintInput image dimensions
upscale_ratio / upscaleroptionalPresent only when upscaling is enabled
colorizeroptionalPresent only when a non-none colorizer is used
mask_rawoptionalPNG base64 of the refined mask (the optimized ctx.mask)
mask_is_refinedboolAlways true when a mask is saved

Each Translation region contains text, translation, translation_raw, translation_rich, angle, font_size, fg_colors, bg_colors, direction, alignment, target_lang, source_lang, line_spacing, letter_spacing, stroke_width, font_family, prob, and similar fields. Do not paste user image data such as mask_raw from a response into documentation or shared logs.

Custom byte format

TranslationResponse.to_bytes() layout: an int32 region count followed by, for each region, minX/minY/maxX/maxY (four int32s), is_bulleted_list (1 byte), angle (float32), prob (float32), foreground color (3-byte RGB), background color (3-byte RGB), and a text map (int32 entry count; each entry is uint32 key length + UTF-8 key + uint32 value length + UTF-8 value). See examples/response.* for decoding examples.

Streaming frame format

Each streaming frame is “1 status byte + 4-byte big-endian length + payload”: status 0 is result bytes, 1 is progress JSON, and 2 is error JSON. The stage in progress JSON covers queued, slot_acquired, task_id, start, image_loading, translator_init, translating, translate_done, processing, transforming. See Streaming protocol for the full protocol and client parsing.

Task status, queue, and concurrency

flowchart TD
    A["Client submits a /translate/* request"] --> B{"verify_translation_auth checks session and permissions"}
    B -->|401 / 403| X["HTTP error response"]
    B -->|passed| C{"track_task_start checks concurrency and daily quota"}
    C -->|429| Y["HTTP 429 CONCURRENT_LIMIT_EXCEEDED / DAILY_QUOTA_EXCEEDED"]
    C -->|passed| D["Acquire a translation semaphore slot"]
    D --> E["Thread pool runs translator.translate or translate_batch"]
    E --> F["Assemble JSON / bytes / PNG / streaming frames"]
    F --> G["Return the response; streaming and batch endpoints also write history"]
  • Concurrency slots come from task_manager.translation_semaphore, defaulting to max_concurrent_tasks=3 (read from server_config); while waiting for a slot, while_streaming() first emits stage: queued (with queue_position), then stage: slot_acquired once the slot is obtained.
  • Active tasks are registered in task_manager.active_tasks with initial status queued, updated to running after the slot is acquired; when an admin cancels a task, streaming tasks receive CancelledError and emit a status-2 error frame.
  • Batch endpoints pass task_id to get_batch_ctx(), which checks is_task_cancelled() before converting and translating each image; a forced or detected cancellation returns 499.
  • Users with offline translation permission (allow_offline_translation) get a never-disconnecting request wrapper in /batch/images, so the task keeps running and writes history even after the client disconnects.

API constraints

  • Session and permissions: every translation endpoint depends on X-Session-Token; a disabled account, expired token, or failed activity refresh returns 401. Permission filtering first overrides disabled parameters, then checks translator/OCR/colorizer/renderer permissions.
  • Configuration source: the config in a request is a full configuration snapshot; the server starts with config/config.json (copied from config-example.json when absent). Values submitted by the user are overridden by user-group/user allow and deny lists and must not be treated as the final effective values.
  • user_env_vars: form endpoints accept uppercase environment-variable key/value pairs that are merged with the user's preset and validated by the API-key policy; a key that does not match the current translator returns 403. Documentation and logs must never show real keys.
  • Adjacent pages: streaming-frame decoding and task-cancellation timing are in Streaming protocol; export/import/colorize/upscale/inpaint endpoints are in Batch, export, and import process; session, permission, and global error formats are in Authentication and errors.
  • Concurrency and history: translation is limited by both the semaphore and per-user concurrency/daily quotas; streaming and batch successes are written to history, whose reading and downloads are documented in History, files, and download tickets.

Developer Guide

Option matrix

Workflow options and endpoint mapping

UI call keyEnglish actual valueSimplified Chinese actual value
Translation Workflow Mode:Translation Workflow Mode:翻译流程模式:
Normal TranslationNormal Translation正常翻译流程
Export TranslationExport Translation导出翻译
Export Original TextExport Original Text导出原文
Import Translation and RenderImport Translation and Render导入翻译并渲染
Colorize OnlyColorize Only仅上色
Upscale OnlyUpscale Only仅超分
Inpaint OnlyInpaint Only仅修复
Start TranslationStart Translation开始翻译
Log output...Log output...日志输出...

Workflow stored-value to endpoint mapping: normal/translate/with-form/image/stream; export_trans/translate/export/translated; export_raw/translate/export/original; import_trans/translate/import/json; colorize/translate/colorize; upscale/translate/upscale; inpaint/translate/inpaint. When localStorage.session_token exists, the frontend sends the token in the X-Session-Token header, and batch requests set an additional 30-minute AbortController timeout.

Errors, cancellation, and status codes

StatusTrigger (current code)Source
200Success: JSON, image, stream, bytes, or the queue-size integerFastAPI default
400/batch/images without images; import/export validation failurestranslation.py:449
401Missing X-Session-Token (NO_TOKEN) or invalid/expired (INVALID_TOKEN)translation_auth.py:253
403Missing translator/OCR/colorizer/renderer permission; user API key does not match the translatortranslation_auth.py:345; core/response_utils.py
422Body validation failure or invalid image data; the global handler returns detail and the bodymain.py:255
429User concurrency limit (CONCURRENT_LIMIT_EXCEEDED) or daily quota (DAILY_QUOTA_EXCEEDED) exceededcore/middleware.py:326, :365
499Batch task forcibly cancelled or detected as cancelledtranslation.py:421, :518
500No result image, translation exception, or service not initializedtranslation.py:527; request_extraction.py

Streaming endpoints do not raise HTTP errors when translation fails midway; they emit a status-2 error frame with {"error": ..., "stage": ...}. HTTP status codes are reserved for authentication, permission, concurrency, quota, and request-validation phases.

File/formatActual role on this pageNotes
manga_translator/server/routes/translation.py31 /translate route declarations and parameter bindingEndpoint inventory, workflows, and error codes follow this file
manga_translator/server/request_extraction.pyTranslateRequest, BatchTranslateRequest, get_ctx, while_streaming, get_batch_ctxImage decoding, slots, task registration, and history saving
manga_translator/server/to_json.pyTranslationResponse, Translation, and the custom byte formatResponse fields and the to_bytes() layout
manga_translator/server/core/response_utils.pytransform_to_json/bytes/image, apply_user_env_varsPlaceholder image, byte/JSON conversion, and API-key policy
manga_translator/server/routes/translation_auth.pyverify_translation_auth, task counting, and quotas401/403/429 and disabled-parameter filtering
manga_translator/server/core/task_manager.pySemaphore, thread pool, active tasks, and cancellationConcurrency defaults and task status
manga_translator/server/myqueue.pyLegacy TaskQueue, the queue-size data sourceRead-only snapshot, not semaphore waiters
manga_translator/server/runtime_api.pyRuntime API overrides (Sakura/OCR/colorizer/renderer)Environment-variable priority; no real keys
manga_translator/server/static/index.html, static/script.jsWeb frontend submission entry and stream parsingUI-text keys and request headers

Code locations

LayerFileWhat was checked
Routesmanga_translator/server/routes/translation.pyEndpoint paths, methods, request/response models, workflows, and status codes
Request/responsemanga_translator/server/request_extraction.py, to_json.py, core/response_utils.pyTranslateRequest/BatchTranslateRequest/TranslationResponse, byte and streaming-frame formats
Auth and limitsmanga_translator/server/routes/translation_auth.py, core/middleware.py401/403/429, disabled-parameter filtering, concurrency, and quotas
Queue and tasksmanga_translator/server/core/task_manager.py, myqueue.pySemaphore, thread pool, active tasks, cancellation, and queue-size
Runtime overridesmanga_translator/server/runtime_api.pyAPI key/base/model environment-variable priority
Web UImanga_translator/server/static/index.html, static/script.js, desktop_qt_ui/locales/en_US.json, zh_CN.jsonWorkflow dropdown, submission endpoints, and the three-column UI texts