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.
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.
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.
Clean the artwork behind the text (adds 1 credit, ignored in BYOK)
# 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).
# 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/translationsRetrieve 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.
/api/v1/meYour 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
/api/v1/pricingPer-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.
/api/v1/translateUpload 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.
/api/v1/keysList your keys with prefix, status, expiry, last usage and request counts. The full key is never returned again.
Returns: keys[]
Cost: Free
/api/v1/keysCreate 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
/api/v1/keys/:idRevoke a key immediately. Requests using it will fail instantly.
Returns: ok
Cost: Free
Projects
Organize your series: source + target languages, chapters, team access.
/api/v1/projectsProjects you own or collaborate on, with your role, chapter counts and languages.
Returns: projects[]
/api/v1/projectsCreate a project, optionally with source/target languages and a template. Gated by the plan project limit.
Body:name, description?, sourceLanguageId?, targetLanguageIds?, templateId?
Returns: project
/api/v1/projects/:idProject detail with its chapters.
Returns: project + chapters[]
/api/v1/projects/:idUpdate name, description, style guide or template.
Body:name?, description?, styleGuide?, templateId?, …
Returns: project
/api/v1/projects/:id/languagesReplace the source and target languages. Gated by the plan language limit.
Body:sourceLanguageId?, targetLanguageIds
Returns: ok
/api/v1/projects/:idDelete 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.
/api/v1/projects/:projectId/chaptersList the chapters of a project.
Returns: chapters[]
/api/v1/projects/:projectId/chaptersCreate 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)
/api/v1/chapters/:idChapter detail with per-page status flags.
Returns: chapter + pages[]
/api/v1/chapters/:idRename or renumber a chapter, change its stage.
Body:title?, chapterNumber?, status?
Returns: chapter
/api/v1/chapters/:idDelete a chapter and its pages.
Returns: ok
/api/v1/chapters/:id/pagesAdd 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.
/api/v1/chapters/:id/dispatch-ocrRun OCR on pages that are not OCR-completed yet.
Returns: dispatchedPageIds, pagesToProcess
Cost: 1 credit per page
/api/v1/chapters/:id/dispatch-translationTranslate 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)
/api/v1/chapters/:id/dispatch-inpaintInpaint (clean) pages that are OCR-completed and not cleaned yet.
Returns: dispatchedPageIds, pagesToProcess
Cost: 1 credit per page
/api/v1/chapters/:id/retry-failedRetry failed or stuck pages — re-runs OCR or translation as needed.
Body:pageIds?
Returns: retriedPageIds, retriedCount
Status & results
Follow processing and fetch the results.
/api/v1/chapters/:id/statusPer-page snapshots (upload/ocr/translation/inpaint status, completed language ids) plus aggregate counts. Poll this, or use webhooks.
Returns: pages[], completedIds[], counts…
/api/v1/chapters/:id/pages/:pageIdPage detail with public image URLs (original, cleaned, thumbnails).
Returns: page
/api/v1/chapters/:id/pages/:pageId/ocrOCR blocks with their lines, polygons, confidence and detected language.
Returns: blocks[] with lines[]
/api/v1/chapters/:id/pages/:pageId/translationsTranslated text per block and language.
Returns: translations[]
/api/v1/chapters/:id/exportFull chapter data bundle (JSON): pages, blocks, translations, languages.
Returns: chapter export data
/api/v1/chapters/:id/export-zipDownload 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).
/api/v1/chapters/:id/renderQueue 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)
/api/v1/chapters/:id/pages/:pageId/rendersRender 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.
/api/v1/webhooksList your webhook endpoints with status and last delivery info.
Returns: webhooks[]
/api/v1/webhooksRegister 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)
/api/v1/webhooks/:idUpdate the URL or events. Re-enables an auto-disabled endpoint.
Body:url?, events?
Returns: webhook
/api/v1/webhooks/:id/regenerate-secretRotate the signing secret. Update your verification code accordingly.
Returns: secret (shown once)
/api/v1/webhooks/:id/deliveriesLast 30 delivery attempts with status and HTTP response code.
Returns: deliveries[]
/api/v1/webhooks/:idDelete 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.
# 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.completedwebhook. - •
pixelRatioupscales 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).
# 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"
fiErrors & rate limits
| Status | Meaning |
|---|---|
| 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 |
| 422 | Validation 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