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
-
Create a token
In My account › API tokens, tick only the scopes the script needs. The secret is shown once.
-
Send the book
POST /api/v1/translation-requeststakes an EPUB, TXT or DOCX chapters, or a JSON document. Libris Translate answers202 Acceptedimmediately. -
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. -
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.
#!/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.
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:readtolibrary: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-Keyheader, a retried upload returns the first request instead of creating a second one. -
Every request ends
A request finishes as
completed,completed_with_residuals,failedwith a reason, orcancelled. 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.translatedto 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/v1only accepts API tokens, and a token never opens the interface's routes. Studio and Pro include the API; with another licence, a valid token gets402 automation_not_licensed. -
The same access for an agent
POST /mcpanswers 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.latestfinds the last one) and only they are translated.?scope=newdownloads just those,?scope=volumethe whole updated volume. -
Parts, prologues, interludes
Chapters of a JSON document take a
kind, apart, alabeland a position (after). TXT and DOCX uploads read them from the file names, andsplit=headingssplits 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 with402 licence_quota_insufficient(orallowance_insufficientfor 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 path | Scope | Purpose |
|---|---|---|
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.