Developer API

The Jokai API

Translate manga, webtoons and comics from your own tools. Send a single image and get everything back in one call, or drive the full pipeline — projects, chapters, OCR, translation, inpainting — and receive final rendered pages identical to the web editor. Every request draws from your plan's credits, exactly like the app.

Bearer token auth·2 usage styles: one-shot & pipeline·Final images rendered server-side·Signed webhooks

Authentication

Requests are authenticated with a personal API key passed as a Bearer token. Create keys in Settings → API (or via the API itself). The full key is shown only once at creation — only a SHA-256 hash is stored, so a lost key cannot be recovered.

Header
Authorization: Bearer jk_live_YOUR_KEY
  • • Keys act as your account — keep them secret. Rotate by creating a new key and revoking the old one (zero downtime).
  • • Optional expiry date per key, revocation is immediate.
  • • API access requires a paid plan — free-plan requests get a 403 upgrade payload.
  • • Every authenticated response carries X-Jokai-Credits (your remaining balance) and rate-limit headers.

Quickstart — one-shot

The fastest way in: POST an image, receive the translated blocks (with bounding boxes), the original image, a cleaned (inpainted) image and timing/credit metadata — in a single synchronous response, typically within 10–60 seconds. Steer the output with a custom prompt and story context, or run your request live below.

Build your request

Configure the request — the code below updates live in every language.

Inpaint the result

Clean the artwork behind the text (adds 1 credit, ignored in BYOK)

cURL
# Translate one image — everything comes back in the response
curl -X POST https://your-jokai-host/api/v1/translate \
  -H "Authorization: Bearer jk_live_YOUR_KEY" \
  -F "file=@page_001.jpg" \
  -F "target_lang=en"

Try it live

Run the request you just built — right here, against this Jokai host. Costs real credits: 1 (OCR) + translation + 1 (inpaint) — BYOK translation is free.

Every example on this page ships in 8 flavors — cURL, Node.js, Python, Go, Rust, PHP, C# and Java. Pick your language in the tabs above a block; every other block follows.

Cost: 1 credit (OCR) + translation (0 with your own API key — BYOK) + 1 credit if inpainted. Use a generous HTTP timeout.

Full pipeline — series & chapters

For whole series: create a project, push chapters with their pages, and the pipeline runs automatically — OCR, translation, inpainting. Pages sharing a contextGroup keep rolling story context, so names and references stay consistent across pages (a Jokai strength).

cURL
# 1. Create a project with its languages
curl -X POST https://your-jokai-host/api/v1/projects \
  -H "Authorization: Bearer jk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My series", "sourceLanguageId": "…", "targetLanguageIds": ["…"]}'

# 2. Create a chapter and upload the pages
curl -X POST https://your-jokai-host/api/v1/projects/$PROJECT_ID/chapters \
  -H "Authorization: Bearer jk_live_YOUR_KEY" \
  -F "title=Chapter 1" -F "chapterNumber=1" -F "status=translation" \
  -F "pages[0][image]=@page_001.jpg" -F "pages[0][pageNumber]=1" \
  -F "pages[1][image]=@page_002.jpg" -F "pages[1][pageNumber]=2" \
  -F "pages[1][contextGroup]=1"
# → OCR starts automatically, translation follows, inpaint if autoInpaint

# 3. Follow the progress
curl -H "Authorization: Bearer jk_live_YOUR_KEY" \
  https://your-jokai-host/api/v1/chapters/$CHAPTER_ID/status

# 4. Fetch the results
curl -H "Authorization: Bearer jk_live_YOUR_KEY" \
  https://your-jokai-host/api/v1/chapters/$CHAPTER_ID/pages/$PAGE_ID/translations

Retrieve results as JSON (translations per block), a chapter export bundle, or a ZIP archive with cleaned page images and per-language translation files.

Endpoint reference

Every endpoint available with your key, grouped by purpose. All paths are relative to your Jokai host.

Account & pricing

Inspect your account, plan limits and per-action credit costs.

GET/api/v1/me

Your account, effective plan (subscription or credit-pack pass), credit balance and plan limits (projects, languages, batch size, storage).

Returns: user, plan (with apiAccess), credits.balance, limits

GET/api/v1/pricing

Per-action credit costs for your account. BYOK-aware: translation shows 0 when your own API key is active.

Returns: costs per action, byok flag

Cost: Free

One-shot translate

Translate a single image in one synchronous request — no project needed. Ideal for scripts, bots and quick integrations.

POST/api/v1/translate

Upload an image, get everything back in the response: source + translated text blocks with their bounding boxes, the original image, an inpainted (cleaned) image, and rich metadata (stage timings, model used, credits consumed). Runs OCR → translation → inpaint synchronously (10–60 s).

Body:multipart: file, target_lang, source_lang?, model?, inpaint?, custom_prompt?, context?

Returns: text[] (source, translation, box), image, inpainted, metadata

Cost: 1 (OCR) + translation (0 with BYOK) + 1 if inpainted

API keys

Create, list and revoke the keys that authenticate your requests.

GET/api/v1/keys

List your keys with prefix, status, expiry, last usage and request counts. The full key is never returned again.

Returns: keys[]

Cost: Free

POST/api/v1/keys

Create a key. The full token is returned exactly once — store it safely. Optional expiry date. Max 10 active keys.

Body:name, expiresAt?

Returns: key + token (shown once)

Cost: Free

DELETE/api/v1/keys/:id

Revoke a key immediately. Requests using it will fail instantly.

Returns: ok

Cost: Free

Projects

Organize your series: source + target languages, chapters, team access.

GET/api/v1/projects

Projects you own or collaborate on, with your role, chapter counts and languages.

Returns: projects[]

POST/api/v1/projects

Create a project, optionally with source/target languages and a template. Gated by the plan project limit.

Body:name, description?, sourceLanguageId?, targetLanguageIds?, templateId?

Returns: project

GET/api/v1/projects/:id

Project detail with its chapters.

Returns: project + chapters[]

PATCH/api/v1/projects/:id

Update name, description, style guide or template.

Body:name?, description?, styleGuide?, templateId?, …

Returns: project

PUT/api/v1/projects/:id/languages

Replace the source and target languages. Gated by the plan language limit.

Body:sourceLanguageId?, targetLanguageIds

Returns: ok

DELETE/api/v1/projects/:id

Delete a project (owner only) and schedule storage cleanup.

Returns: ok

Chapters & pages

Upload pages and let the pipeline run. Pages grouped with contextGroup share rolling story context for consistent translations.

GET/api/v1/projects/:projectId/chapters

List the chapters of a project.

Returns: chapters[]

POST/api/v1/projects/:projectId/chapters

Create a chapter and upload its pages in one multipart request. Quota gates run first (subscription, batch size, credits, storage), then OCR + thumbnails + durable upload are dispatched automatically.

Body:multipart: title, chapterNumber, status, autoInpaint?, pages[i][image], pages[i][pageNumber]?, pages[i][contextGroup]?

Returns: chapter + pages[]

Cost: Per page: OCR 1 + translation (+ inpaint if auto)

GET/api/v1/chapters/:id

Chapter detail with per-page status flags.

Returns: chapter + pages[]

PATCH/api/v1/chapters/:id

Rename or renumber a chapter, change its stage.

Body:title?, chapterNumber?, status?

Returns: chapter

DELETE/api/v1/chapters/:id

Delete a chapter and its pages.

Returns: ok

POST/api/v1/chapters/:id/pages

Add pages to an existing chapter (multipart, same fields as chapter creation).

Body:multipart: pages[i][image], pages[i][pageNumber]?, autoInpaint?

Returns: pages[]

Pipeline dispatch

Trigger or re-run pipeline stages. All endpoints re-check quotas and return the dispatched page ids.

POST/api/v1/chapters/:id/dispatch-ocr

Run OCR on pages that are not OCR-completed yet.

Returns: dispatchedPageIds, pagesToProcess

Cost: 1 credit per page

POST/api/v1/chapters/:id/dispatch-translation

Translate missing page/language pairs. Context-group aware. An optional model override (plan-gated) applies to this dispatch only.

Body:model?

Returns: dispatchedPageIds, languageCount, alreadyTranslated

Cost: Per page & language: model cost (0 with BYOK)

POST/api/v1/chapters/:id/dispatch-inpaint

Inpaint (clean) pages that are OCR-completed and not cleaned yet.

Returns: dispatchedPageIds, pagesToProcess

Cost: 1 credit per page

POST/api/v1/chapters/:id/retry-failed

Retry failed or stuck pages — re-runs OCR or translation as needed.

Body:pageIds?

Returns: retriedPageIds, retriedCount

Status & results

Follow processing and fetch the results.

GET/api/v1/chapters/:id/status

Per-page snapshots (upload/ocr/translation/inpaint status, completed language ids) plus aggregate counts. Poll this, or use webhooks.

Returns: pages[], completedIds[], counts…

GET/api/v1/chapters/:id/pages/:pageId

Page detail with public image URLs (original, cleaned, thumbnails).

Returns: page

GET/api/v1/chapters/:id/pages/:pageId/ocr

OCR blocks with their lines, polygons, confidence and detected language.

Returns: blocks[] with lines[]

GET/api/v1/chapters/:id/pages/:pageId/translations

Translated text per block and language.

Returns: translations[]

GET/api/v1/chapters/:id/export

Full chapter data bundle (JSON): pages, blocks, translations, languages.

Returns: chapter export data

POST/api/v1/chapters/:id/export-zip

Download a ZIP archive: cleaned page images + per-language translation JSON files + manifest. Gated by the plan export entitlement.

Body:languageIds?

Returns: application/zip download

Final rendered images

Get the fully composed page — cleaned artwork with translated text typeset exactly like in the web editor (fonts, strokes, effects, vertical text).

POST/api/v1/chapters/:id/render

Queue server-side rendering of the final composed image for the chapter's pages and languages. Rendering reuses the web editor engine, so output is identical to what you see in the editor. Poll the render list or wait for the page.render.completed webhook.

Body:languageIds?, pageIds?, pixelRatio?, format? (png|webp)

Returns: renders[] (pageId, languageId, status)

Cost: Free (plan resolution limits apply)

GET/api/v1/chapters/:id/pages/:pageId/renders

Render status and public image URL per language.

Returns: renders[] (language, status, url)

Webhooks

Get notified on your own server when processing finishes. HMAC-SHA256 signed (Stripe-style), retried with backoff, auto-disabled after 5 consecutive failures.

GET/api/v1/webhooks

List your webhook endpoints with status and last delivery info.

Returns: webhooks[]

POST/api/v1/webhooks

Register an endpoint. The URL must be HTTPS on a public host (SSRF-hardened). The signing secret is returned exactly once.

Body:url (HTTPS, public), events[]

Returns: webhook + secret (shown once)

PATCH/api/v1/webhooks/:id

Update the URL or events. Re-enables an auto-disabled endpoint.

Body:url?, events?

Returns: webhook

POST/api/v1/webhooks/:id/regenerate-secret

Rotate the signing secret. Update your verification code accordingly.

Returns: secret (shown once)

GET/api/v1/webhooks/:id/deliveries

Last 30 delivery attempts with status and HTTP response code.

Returns: deliveries[]

DELETE/api/v1/webhooks/:id

Delete a webhook endpoint.

Returns: ok

Final rendered images

Other translation APIs stop at the text. Jokai returns the final composed page — cleaned artwork with the translated text typeset on top, exactly as it appears in the Jokai web editor. Fonts, strokes, outlines, vertical Japanese text, gradients and effects are rendered by the very same engine, on our servers.

cURL
# Queue server-side rendering (same engine as the web editor)
curl -X POST https://your-jokai-host/api/v1/chapters/$CHAPTER_ID/render \
  -H "Authorization: Bearer jk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"pixelRatio": 2}'

# Poll the render status / get the image URL
curl -H "Authorization: Bearer jk_live_YOUR_KEY" \
  https://your-jokai-host/api/v1/chapters/$CHAPTER_ID/pages/$PAGE_ID/renders

# Download the final composed image
curl -o final_page.png "$RENDER_URL"
  • • Rendering is asynchronous: queue it, then poll the render list or listen for the page.render.completed webhook.
  • •pixelRatio upscales the output (2× default 1×), limited by your plan's export resolution.
  • • Renders are free — you only paid for the pipeline that produced them.

Webhooks

Register an HTTPS endpoint and get notified when processing finishes — no polling. Deliveries are signed (Stripe-style X-Jokai-Signature: t=…,v1=…), retried with exponential backoff, and the endpoint is auto-disabled after 5 consecutive failures. URLs must be HTTPS on a public host (SSRF-hardened).

cURL
# Verify a Jokai webhook signature with openssl (bash)
# SIGNATURE is the value of the "X-Jokai-Signature" header: t=…,v1=…
# payload.json contains the RAW request body
TIMESTAMP=$(echo "$SIGNATURE" | cut -d, -f1 | cut -d= -f2)
GIVEN=$(echo "$SIGNATURE" | cut -d, -f2 | cut -d= -f2)

EXPECTED=$(printf '%s.%s' "$TIMESTAMP" "$(cat payload.json)" \
  | openssl dgst -sha256 -hmac "$JOKAI_WEBHOOK_SECRET" | awk '{print $NF}')

NOW=$(date +%s)
if [ "$EXPECTED" = "$GIVEN" ] && [ $((NOW - TIMESTAMP)) -lt 300 ]; then
  echo "Signature valid"
fi

Errors & rate limits

StatusMeaning
401 Missing, malformed, revoked or expired key
403 Plan quota denial (with upgrade payload) or provider auth failure
404 Resource doesn't exist or belongs to another user
422Validation error (field details)
429 Rate limit exceeded — see Retry-After
502 One-shot translate: internal OCR/inpaint service failure

Rate limiting uses a per-key token bucket: 120 requests per minute of sustained throughput with the full budget available as an immediate burst (default; configurable server-side). Every response includes X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset.

Credits & costs

API usage draws from the same credit balance as the web app — subscription credits first, purchased packs after. Check GET /api/v1/pricing for the exact costs applied to your account (translation is free if you use your own API key — BYOK).

OCR

1 credit per page

Translation

Model-dependent · 0 with BYOK

Inpaint

1 credit per page

Renders & webhooks

Free

File limits

  • • Max size: 50 MB per image
  • • Max side: 20 000 px
  • • Max resolution: 100 megapixels
  • • Formats: jpg, jpeg, png, webp

Ready to build?

Create your first API key and ship your integration today.

Go to Settings → API

We use essential cookies to keep you logged in and remember your preferences. We only set analytics cookies with your consent. See our Cookie Policy.