# EPUB Validator & Publishing Preflight API (`epubpreflight/epub-preflight`) Actor

Validate EPUB files before publishing with one agent-friendly API call. Runs native structural QA, EPUBCheck 5.3.0 and DAISY Ace 1.4.6, returns structured release decisions, root causes and next actions, and can apply deterministic safe fixes. From $0.01; full preflight $0.05.

- **URL**: https://apify.com/epubpreflight/epub-preflight.md
- **Developed by:** [Ezra Evercreech](https://apify.com/epubpreflight) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / full epub preflight

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## EPUB Validator & Publishing Preflight API

**Turn one EPUB URL into a machine-readable publishing decision.**

EPUB Preflight is an agent-first validation API for automated ebook publishing workflows.

It can run:

- native EPUB structural and publishing QA
- EPUBCheck 5.3.0
- DAISY Ace 1.4.6 accessibility checks
- deterministic safe fixes

The result tells an agent whether the EPUB is:

- `ready` — clean and ready to publish
- `review` — publishable, but warnings remain
- `blocked` — errors require repair

It also returns normalized issues, deduplicated root causes, repair metadata, and ordered next actions. Native QA includes conservative Kindle cover-risk warnings for SVG covers and PNG covers that declare alpha/transparency.

### Pricing

| Profile | Validation | Price |
| --- | --- | ---: |
| Native | Native EPUB Preflight checks | **$0.01** |
| Conformance | Native + EPUBCheck | **$0.02** |
| Full | Native + EPUBCheck + DAISY Ace | **$0.05** |

Safe deterministic fixes and a repaired EPUB artifact are included when requested.

Only the custom validation profile event is charged on completed validations. Incomplete validation and operational failures do not incur the $0.01 / $0.02 / $0.05 profile event; the separately listed Apify Actor Start synthetic event may still apply.

### Why use this instead of running EPUBCheck directly?

EPUBCheck remains the standards-focused validator inside the workflow.

EPUB Preflight adds the automation layer around it:

- one hosted API call
- no Java, Node.js, EPUBCheck, or Ace setup on the client
- unified machine-readable output
- `ready` / `review` / `blocked` release decisions
- root-cause grouping and cascade suppression
- agent-facing repair instructions and ordered next actions
- conservative automatic fixes where the correction is deterministic

It is designed to make EPUB validation easy to consume inside AI-agent and automated publishing pipelines.

### Typical agent loop

```text
build EPUB
    ↓
run EPUB Preflight
    ↓
READY ─────────→ publish
REVIEW ────────→ inspect warnings
BLOCKED ───────→ repair → rebuild → revalidate
```

For the shortest decision path, inspect:

```text
validation_complete
status
publishable
```

If the EPUB is not ready, consume `actionable_issues`, `root_causes`, and `next_actions` instead of parsing validator prose.

### Input

```json
{
  "epubUrl": "https://example.com/book.epub",
  "applySafeFixes": false,
  "runEpubcheck": true,
  "runAce": true
}
```

`epubUrl` must be a public HTTP(S) URL. Private, loopback, link-local, and other non-public network targets are rejected. Downloads are limited to 100 MiB.

Supported validator combinations are Full (EPUBCheck + Ace), Conformance (EPUBCheck only), and Native (both external validators off). Ace without EPUBCheck is rejected so the executed validation stack always matches the advertised billing profile.

### Output

The run exposes three output links:

- **Full preflight result** — the `OUTPUT` record in the default key-value store
- **Run summary** — one compact row in the default dataset
- **Generated artifacts** — a repaired EPUB when safe fixes changed the input

The full result preserves the normal EPUB Preflight envelope under `preflight`, while adding Actor-level request, download, and validator metadata.

A validator finding is not an Actor execution failure. Accessibility or conformance violations are returned normally in the unified result. Operational failures such as an invalid URL or failed download make the Actor run fail and write a structured `OUTPUT` record when possible.

### Runtime

The Actor image pins:

- Python 3.11
- Java 17
- EPUBCheck 5.3.0 with verified release SHA-256
- Node.js 20
- DAISY Ace 1.4.6 using the headless `ace-puppeteer` runner
- Apify Python SDK 4.0.1

Launch memory is capped at 2048 MiB. Hosted Ace validation uses a 600-second subprocess budget.

### Pay per event

The Actor uses three one-time custom events:

- `native-preflight` — $0.01
- `conformance-preflight` — $0.02
- `full-preflight` — $0.05

Safe fixes and repaired EPUB return are included in the selected profile price.

Only `validation_complete=true` outcomes trigger the custom profile event. `ready`, `review`, and `blocked` are all completed validation outcomes. The Apify Actor Start synthetic event is separate from this completion-based charge.

### Agent REST reference

The hosted v0.6.1 contract has been verified end to end against the immutable production golden: raw Apify API execution returned `ready` with zero errors/warnings, and the dependency-free Python consumer at `examples/apify_agent_client.py` independently returned `continue_release`.

For automated publishing agents, prefer the asynchronous run/poll/fetch flow and read `validation_complete` before making any release decision.

The hosted safe-fix path has also been verified end to end: repaired EPUB bytes are stored as `ARTIFACT_REPAIRED_EPUB` and can be fetched by the reference client with `--download-repaired`.

See:

- `docs/apify-agent-client.md`
- `docs/hosted-api-baseline.md`
- `docs/hosted-repaired-artifact-smoke.md`

# Actor input Schema

## `epubUrl` (type: `string`):

Public HTTP(S) EPUB URL to validate. Redirects are allowed, but private or local network targets are rejected. A production-Full-verified and Kindle-verified golden sample with a flattened RGB JPEG cover, NCX compatibility, and visible navigation is prefilled.

## `applySafeFixes` (type: `boolean`):

Create a repaired EPUB when deterministic safe fixes are available. No extra charge beyond the selected validation profile.

## `runEpubcheck` (type: `boolean`):

Include EPUBCheck 5.3.0 conformance validation in the unified result. Native + EPUBCheck profile: $0.02. If EPUBCheck is disabled, DAISY Ace must also be disabled.

## `runAce` (type: `boolean`):

Include DAISY Ace 1.4.6 accessibility validation in the unified result. Ace requires EPUBCheck; both enabled is the Full $0.05 profile.

## Actor input object example

```json
{
  "epubUrl": "https://raw.githubusercontent.com/heavyrain39/epub-preflight-samples/7353024813a9dda752772e33903330ab18f6a5e2/reverse-waterfall/reverse-waterfall-demo.epub",
  "applySafeFixes": false,
  "runEpubcheck": true,
  "runAce": true
}
```

# Actor output Schema

## `result` (type: `string`):

Canonical machine-readable result. Inspect validation\_complete, status, and publishable first, then use actionable issues, root causes, repair metadata, and ordered next actions when work remains.

## `summary` (type: `string`):

One-row dataset summary for dashboards, automations, and quick release gating without parsing the full result.

## `artifacts` (type: `string`):

Safely repaired EPUB output, available only when deterministic fixes were requested and changed the input file.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "epubUrl": "https://raw.githubusercontent.com/heavyrain39/epub-preflight-samples/7353024813a9dda752772e33903330ab18f6a5e2/reverse-waterfall/reverse-waterfall-demo.epub"
};

// Run the Actor and wait for it to finish
const run = await client.actor("epubpreflight/epub-preflight").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "epubUrl": "https://raw.githubusercontent.com/heavyrain39/epub-preflight-samples/7353024813a9dda752772e33903330ab18f6a5e2/reverse-waterfall/reverse-waterfall-demo.epub" }

# Run the Actor and wait for it to finish
run = client.actor("epubpreflight/epub-preflight").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "epubUrl": "https://raw.githubusercontent.com/heavyrain39/epub-preflight-samples/7353024813a9dda752772e33903330ab18f6a5e2/reverse-waterfall/reverse-waterfall-demo.epub"
}' |
apify call epubpreflight/epub-preflight --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,epubpreflight/epub-preflight"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rOYWv2g09UsosZTOr/builds/NhWBw8DcmYNUnoZbe/openapi.json
