EPUBCheck as an API

Check EPUB files with EPUBCheck over HTTPS: one call returns EPUBCheck's full JSON report and a summary, for 2 credits. No Java to install.

Last updated

Endpoint POST /v1/epubcheck/check with the EPUB as the multipart field file
Price 2 credits per check, whatever the verdict. A rejected or failed call costs nothing.
Limits 25 MB per file and 45 seconds per check, one file per call
Response EPUBCheck's JSON report (checker, publication, items, messages) plus summary

EPUBCheck is the W3C's conformance checker for EPUB publications. It checks the ZIP container, the package document, the navigation and every content document of an EPUB 2 or EPUB 3 file against the EPUB specifications. Many ebook stores and distributors require a file to pass it before they accept it.

Here it runs behind one HTTPS endpoint: send the file, get EPUBCheck's own JSON report back, plus a summary with the verdict.

Price and limits

A check costs 2 credits, whatever the verdict: a file with errors is a normal answer (200), with the errors in messages. A call that is rejected or fails (any status from 400 up) costs nothing. Without an API key, a check spends the free daily allowance of your IP address; the free allowance and the plans are on the pricing page.

  • 25 MB per file, one file per call.
  • 45 seconds per check. A longer check is stopped and answers 504 engine_timeout.
  • EPUBCheck runs one check at a time. While it is busy, a call answers 429 engine_busy with a Retry-After header: wait that many seconds and send it again.

Self-host or hosted

EPUBCheck ships as a Java command-line tool. Running it yourself means a Java runtime on every machine that checks files, the EPUBCheck release and its updates, and a new JVM for each check: about 512 MB of memory and a second or two of start-up per file. To call it from another service, you also write and run a small HTTP wrapper around it.

Hosted, it is one API key and one HTTPS call, from any language, with nothing to install or update.

Quickstart: curl

curl -sS -X POST https://api.pagespool.com/v1/epubcheck/check \
  -H "X-API-Key: $PAGESPOOL_KEY" \
  -F file=@book.epub | jq .summary

summary is the verdict at a glance:

{"valid": false, "fatal": 0, "error": 2, "warning": 1}

The rest of the response is EPUBCheck's report as EPUBCheck writes it.

Quickstart: Python

import httpx

with open("book.epub", "rb") as f:
    resp = httpx.post(
        "https://api.pagespool.com/v1/epubcheck/check",
        headers={"X-API-Key": KEY},
        files={"file": ("book.epub", f, "application/epub+zip")},
        timeout=60,
    )
resp.raise_for_status()
report = resp.json()
print(report["summary"])
for message in report["messages"]:
    print(message["severity"], message["ID"], message["message"])

The response

A 200 response is EPUBCheck's JSON report, unchanged, with one key added:

  • checker: the EPUBCheck version (checkerVersion) and its own counts.
  • publication: the metadata EPUBCheck read, such as title, language and ePubVersion.
  • items: every file in the EPUB, with its media type.
  • messages: one entry per problem, with ID (for example RSC-005), severity, message, locations (path, line, column; -1 when unknown) and suggestion. EPUBCheck lists all places of one problem under one message.
  • summary: valid (no FATAL and no ERROR message) and the number of fatal, error and warning messages.

Errors are RFC 9457 problems (application/problem+json) with a stable code: payload_too_large (413), engine_busy (429), engine_failed (502), engine_unavailable (503, with Retry-After) and engine_timeout (504).

API keys

A key goes in one of three places:

  • the X-API-Key header: -H "X-API-Key: $PAGESPOOL_KEY";
  • a bearer token: -H "Authorization: Bearer $PAGESPOOL_KEY";
  • HTTP Basic auth with the key as the password and any user name: curl -u "x:$PAGESPOOL_KEY" …, or a URL like https://x:<key>@… for a client that only takes a URL.

Never put the key in the path or the query string: those end up in logs.

Free tool and MCP

To try a file without writing code, use the free EPUB validator (files up to 4 MB).

AI agents get the same check from the MCP server at https://api.pagespool.com/mcp/epubcheck/. Its tool check_epub takes the EPUB as base64 (up to 4 MB) or as an https link, and returns the summary and the 20 most severe messages. It costs 2 credits per call, like the API.

Trademarks

EPUBCheck is a project of the W3C; pagespool is not affiliated.

FAQ

What does EPUBCheck check?
EPUBCheck checks an EPUB 2 or EPUB 3 file against the EPUB specifications: the ZIP container, the package document, the navigation and every content document. Each problem it finds is a message with a severity: FATAL, ERROR, WARNING, USAGE or INFO.
When is a file valid?
When the report has no FATAL and no ERROR message. Warnings alone do not make a file invalid. The summary in each response says so in valid, next to the fatal, error and warning counts.
Do I need an API key?
No. Without a key, a check spends the free daily allowance of your IP address. A free account with a key gets a daily allowance and monthly credits of its own; plans are on the pricing page.