Automation API

Send a book, get it back translated.

The automation API lets a script or another server hand books to Libris Translate without opening the web interface. The whole pipeline runs under the autopilot, and every request ends either with a result or with a stated reason.

The principle

  1. Create a token

    In My account › API tokens, tick only the scopes the script needs. The secret is shown once.

  2. Send the book

    POST /api/v1/translation-requests takes an EPUB, TXT or DOCX chapters, or a JSON document. Libris Translate answers 202 Accepted immediately.

  3. Follow it

    Poll the status with ?wait= to hold the call open until the request ends (up to 600 seconds), or let a signed webhook notify you, including after each batch of translated chapters.

  4. Get the result

    The translated EPUB, checked with EPUBCheck, a bilingual EPUB, or JSON, text or a ZIP of chapters, with the completion report.

A complete example

Upload an EPUB, wait for the end, download the translated book and read the report. The script expects LIBRIS_URL, LIBRIS_TOKEN and PROVIDER_ID in the environment and uses curl and jq. It is copied unchanged from the API guide that ships with Libris Translate.

bash
#!/usr/bin/env bash
set -euo pipefail

REQUEST_ID=$(curl -sS -X POST "$LIBRIS_URL/api/v1/translation-requests" \
  -H "Authorization: Bearer $LIBRIS_TOKEN" \
  -H "Idempotency-Key: book-fr-1" \
  -F "file=@book.epub" -F target_language=fr -F provider_id="$PROVIDER_ID" \
  | jq -r .request_id)

while :; do   # each call answers when the request ends, or after 60 seconds
  STATUS=$(curl -sS "$LIBRIS_URL/api/v1/translation-requests/$REQUEST_ID?wait=60" \
    -H "Authorization: Bearer $LIBRIS_TOKEN" | jq -r .status)
  case "$STATUS" in completed|completed_with_residuals|failed|cancelled) break ;; esac
done
echo "Request ended: $STATUS"

if [ "$STATUS" = completed ] || [ "$STATUS" = completed_with_residuals ]; then
  curl -sS "$LIBRIS_URL/api/v1/translation-requests/$REQUEST_ID/result" \
    -H "Authorization: Bearer $LIBRIS_TOKEN" -o book.fr.epub
fi
curl -sS "$LIBRIS_URL/api/v1/translation-requests/$REQUEST_ID" \
  -H "Authorization: Bearer $LIBRIS_TOKEN" | jq '.report | {outcome, residual_total, usage}'

An example client with nothing to install

examples/libris_client.py is a small Python client that only uses the standard library. It sends an EPUB, TXT chapters or a JSON document, long-polls until the end, downloads the result, backs off when rate-limited, and receives webhooks after checking their signature. It ships with Libris Translate in examples/; run it as a command or import it into your own code.

bash
export LIBRIS_URL=https://libris.example.org LIBRIS_TOKEN=lbr_xxxxxxxx_...
python3 examples/libris_client.py epub book.epub --target-language fr --provider-id "$PROVIDER_ID" --out book.fr.epub
LIBRIS_WEBHOOK_SECRET=... python3 examples/libris_client.py webhooks --port 8080

Built for scripts that run unattended

  • Scoped tokens

    Nine scopes, from series:read to library:delete, with optional expiry and immediate revocation. Tokens are stored as SHA-256 hashes and limited to 120 requests a minute each by default.

  • Idempotent requests

    With an Idempotency-Key header, a retried upload returns the first request instead of creating a second one.

  • Every request ends

    A request finishes as completed, completed_with_residuals, failed with a reason, or cancelled. None stays running forever.

  • Signed webhooks

    HMAC-SHA256 signatures, allow-listed hosts only, no private addresses unless you allow them, and up to six attempts in all by default. Subscribe to chapters.translated to hear about each batch of chapters.

  • A report with every result

    Passage states, passages kept in the original and why, estimated and actual cost, the passages and chapters to review first, durations, and the decisions of the import and the autopilot.

  • Separate from the interface

    /api/v1 only accepts API tokens, and a token never opens the interface's routes. Studio and Pro include the API; with another licence, a valid token gets 402 automation_not_licensed.

  • The same access for an agent

    POST /mcp answers the Model Context Protocol with the same tokens and scopes, for opencode, Claude Code or Codex. Scripts use the REST API; agents use MCP.

  • Series followed over time

    Send new chapters to the volume that holds the earlier ones (volume.latest finds the last one) and only they are translated. ?scope=new downloads just those, ?scope=volume the whole updated volume.

  • Parts, prologues, interludes

    Chapters of a JSON document take a kind, a part, a label and a position (after). TXT and DOCX uploads read them from the file names, and split=headings splits one file at its chapter headings.

  • Budgets and a fair queue

    A token can have a monthly or total cost budget (402 budget_exceeded), a priority ceiling and its own quotas (429 queue_full). A book is counted when it is added: one that does not fit in what is left of the licence's word quota plus the margin is refused whole with 402 licence_quota_insufficient (or allowance_insufficient for the account's own quota), and nothing is imported. The status says where the request is waiting in the queue, and why.

Endpoints

Method and pathScopePurpose
POST /api/v1/translation-requests content:write (+ pipeline:start) Send an EPUB, TXT or DOCX chapters, or a JSON document
GET /api/v1/translation-requests/{id} jobs:read Status, progress and report (?wait= to long-poll)
POST …/{id}/pause · …/resume · …/cancel jobs:control Pause, resume or cancel the request's job
GET /api/v1/translation-requests/{id}/result results:read Download the result (EPUB, bilingual EPUB, JSON, TXT or ZIP): the request's chapters, only the new ones, or the whole volume (?scope=)
GET /api/v1/providers content:write List the providers a request may use
GET /api/v1/series · /api/v1/series/{id} series:read List your series, or one series and its volumes
POST /api/v1/series/{id}/jobs/{action} jobs:control (+ pipeline:start) Start, pause, resume or cancel the jobs of a whole series you own
GET /api/v1/glossaries · …/{id} · …/{id}/export/{format} series:read List your shared glossaries, read one, or download it as JSON, CSV or TBX
POST /api/v1/glossaries · …/{id}/import content:write Create a shared glossary or import terms into it (?dry_run=true to preview)
GET · PUT /api/v1/series/{id}/shared-glossary series:read · content:write Read or change the shared glossary a series follows

The full reference

Request options, the JSON document format, status and report fields, webhook verification, errors and limits are all in the reference below and in the API guide that ships with Libris Translate.