# H5P Package Checker (.h5p Preflight) (`madrasco/h5p-package-checker`) Actor

Checks .h5p e-learning packages against the published H5P file specification: h5p.json and library.json fields, bundled library versions, content.json, file types, missing image alt text and oversize files. One report row per package, plus HTML/Markdown report.

- **URL**: https://apify.com/madrasco/h5p-package-checker.md
- **Developed by:** [Madrasco](https://apify.com/madrasco) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## H5P Package Checker (.h5p Preflight)

Check **.h5p** interactive-content packages before you upload them to Moodle, WordPress, Drupal, an LMS or H5P.com. Give the actor one or more `.h5p` file URLs; for each package it returns **one dataset row** with a pass/fail verdict, the package facts (title, main content type and version, bundled libraries, size) and a list of findings. Each finding has a **severity**, the **rule** it breaks, the **location** in the package, a plain-English message and the **source** it is based on. A readable **HTML and Markdown report** goes to the key-value store.

### What it checks

Against the published H5P file specification (h5p.org: *The .h5p Specification*, *File Structure*, *Package Definition*, *Library Definition*, *Semantics Definition*, *Allowed File Extensions*):

| Rule | Severity | Based on |
|---|---|---|
| File is a readable zip; `h5p.json` at the root (with a hint when the package was zipped from its parent folder) | error | .h5p Specification, File Structure |
| `h5p.json` is valid JSON with the mandatory `title`, `mainLibrary`, `language`, `preloadedDependencies`, `embedTypes` | error | Package Definition |
| `embedTypes` only `div`/`iframe`; dependencies well-formed; main library listed in `preloadedDependencies` | error | Package Definition |
| Language is a two-letter ISO 639-1 code or `und` | warning | Package Definition |
| License code is one of the listed codes | note | Package Definition |
| Every library folder has a valid `library.json` with `title`, `machineName`, `majorVersion`, `minorVersion`, `patchVersion`, `runnable`; version numbers are whole numbers; machine name uses allowed characters | error | Library Definition |
| Library folder is named `machineName` or `machineName-major.minor`; no library bundled twice | error | Library Definition, H5P core validator |
| Files listed in `preloadedJs` / `preloadedCss` exist | error | Library Definition |
| Runnable libraries have a valid `semantics.json`; translation files (`language/*.json`) are valid JSON | error | .h5p Specification, Semantics Definition, H5P core validator |
| **Dependencies resolve**: every `preloadedDependencies` / `dynamicDependencies` entry (package and libraries) is bundled in the required major.minor version | error if a different version is bundled; warning if not bundled at all (the target site must already have it) | .h5p Specification, Library Definition |
| **Editor libraries resolve**: every `editorDependencies` entry (e.g. `H5PEditor.*`) is bundled. H5P's upload check counts editor dependencies as required, so a missing one usually makes the upload fail with "Missing required library …" unless the site already has it installed (H5P skips this check when the site has a newer version of the package's main content type) | warning | H5P core validator (h5p-php-library) |
| `content/content.json` present and valid JSON; every file it refers to is in the package | warning / error | .h5p Specification, Semantics Definition |
| **File types** on the H5P allowed-extensions list (HTML files are flagged) | error (note when the type is missing from the published list page but the H5P core default whitelist accepts it, e.g. `.woff2`, `.eot`: default installs accept these) | Allowed File Extensions, H5P core default whitelist |
| **File types the core validator rejects in `content/`**: `.svg`, `.js`, `.css`, `.xml` are on the published list, but the H5P core default whitelist accepts them only inside library folders. Default installs of the H5P plugins for Moodle (mod\_hvp), WordPress and Drupal reject them in `content/` | warning | H5P core validator (h5p-php-library default content whitelist) |
| **Images without alternative text**, where the content type's own `semantics.json` provides an alt-text field (e.g. H5P.Image "Alternative text"), including images inside nested content (for example the slides of an Image Slider, or Course Presentation slides inside an Interactive Book page), found by following each bundled content type's semantics; images marked decorative are counted but need no alt text | warning | Semantics Definition |
| Oversize files and packages (limits you set) | warning | practice check |
| `__MACOSX`, `.DS_Store`, stray root files, unused content files, unsafe archive paths | warning / note / error | practice checks |

Practice checks are labelled as such in the `source` field; they are not rules of the specification.

### What it does not do

- It checks against the **published H5P file specification**; it does **not guarantee that a package uploads or runs on every platform**. Sites can allow other file types, have other library versions installed and set their own upload limits.
- It does not run the content, check JavaScript, scan for viruses or check the accessibility of anything other than image alt-text fields the content type exposes.
- Alt-text checks only cover content types whose `semantics.json` is bundled in the package.

### Input

- **.h5p file URLs** (required): direct download links, up to 50 per run. Links must work without a login (for example a share link from your storage).
- **Include notes** (default on), **Flag single files larger than** (default 20 MB), **Flag packages larger than** (default 200 MB), **Maximum download size** (default 200 MB; the run needs about twice this in memory, and the default 512 MB run memory covers it; raise the run memory before raising this limit).

### Output

**Dataset**: one row per package (view "Packages"), with the findings listed in `issues` (view "Issues" shows one line per finding):

```json
{"url": "https://example.com/quiz.h5p", "verdict": "fail", "errors": 1, "warnings": 1, "infos": 0,
 "title": "Demo", "mainLibrary": "H5P.CoursePresentation", "mainLibraryVersion": "1.22", "libraries": 31,
 "issues": [{"severity": "error", "rule": "library-file-missing", "location": "H5P.Image-1.1/image.js",
             "message": "preloadedJs lists 'image.js' but the file is not in folder 'H5P.Image-1.1'.",
             "source": "H5P, Library Definition (library.json), https://h5p.org/library-definition"}]}
```

A package that cannot be downloaded gets a row with verdict `fetch-failed`.

**Key-value store**: `REPORT.html` and `REPORT.md` (verdict per package, issues by rule, issue table, sources), `OUTPUT` (JSON totals).

### Privacy

Your package is downloaded into the run, checked in memory and not kept by us beyond your own Apify storage. Nothing is sent anywhere else.

### Support

Open an issue on the actor's Issues tab. This actor is built and maintained with AI assistance by Madrasco; a human owner can be reached on request through the Issues tab.

H5P is a registered trademark of H5P Group. This actor is independent and not affiliated with or endorsed by H5P Group.

# Changelog

This Actor's version history is a separate document: https://apify.com/madrasco/h5p-package-checker/changelog.md

# Actor input Schema

## `urls` (type: `array`):

Direct download links to .h5p files (up to 50 per run). Each must be reachable without a login, e.g. a share link from your storage.

## `includeNotes` (type: `boolean`):

Also list informational notes (file types only the H5P core default list accepts, content files nothing refers to). Errors and warnings are always listed.

## `maxFileMb` (type: `integer`):

Warn about any file inside the package larger than this. Set it to your LMS's per-file limit.

## `maxPackageMb` (type: `integer`):

Warn when the whole .h5p is larger than this. Set it to your LMS's upload limit.

## `maxDownloadMb` (type: `integer`):

Packages larger than this are reported as a download failure. The run needs about 2x this in memory: the default 512 MB run memory covers the default 200 MB; raise the run memory (Run options) before raising this.

## Actor input object example

```json
{
  "urls": [
    "https://raw.githubusercontent.com/Lumieducation/H5P-Nodejs-library/master/test/data/validator/valid2.h5p"
  ],
  "includeNotes": true,
  "maxFileMb": 20,
  "maxPackageMb": 200,
  "maxDownloadMb": 200
}
```

# Actor output Schema

## `packages` (type: `string`):

One dataset row per .h5p package with its status and issue counts (the Issues view lists each issue).

## `report` (type: `string`):

Readable report of all checked packages (a Markdown copy is stored as REPORT.md).

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

Totals across all packages.

# 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 = {
    "urls": [
        "https://raw.githubusercontent.com/Lumieducation/H5P-Nodejs-library/master/test/data/validator/valid2.h5p"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("madrasco/h5p-package-checker").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 = { "urls": ["https://raw.githubusercontent.com/Lumieducation/H5P-Nodejs-library/master/test/data/validator/valid2.h5p"] }

# Run the Actor and wait for it to finish
run = client.actor("madrasco/h5p-package-checker").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 '{
  "urls": [
    "https://raw.githubusercontent.com/Lumieducation/H5P-Nodejs-library/master/test/data/validator/valid2.h5p"
  ]
}' |
apify call madrasco/h5p-package-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,madrasco/h5p-package-checker"
        }
    }
}
```

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/9bcTMkvahEJNqMcBr/builds/k6VrIA2UoYKNsyh6b/openapi.json
