IIIF APIiiif.io ↗
Fetch, normalize, and validate IIIF Presentation API manifests. Discover community events, news, and cookbook recipes from iiif.io via a single REST API.
What is the IIIF API?
This API covers 6 endpoints that interact with the IIIF ecosystem: fetch any public IIIF Presentation API manifest with get_manifest, normalize its metadata into a flat structure with version detection, validate it against the official presentation-validator.iiif.io service, and retrieve community events, news articles, and cookbook implementation recipes. Each manifest response exposes fields like items, label, id, and type directly from the source manifest.
curl -X GET 'https://api.parse.bot/scraper/3f99f0f1-1d32-49cb-a9d7-962e6e9ba27c/get_manifest?url=https%3A%2F%2Fiiif.io%2Fapi%2Fcookbook%2Frecipe%2F0009-book-1%2Fmanifest.json' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace iiif-io-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: IIIF Ecosystem API — validate manifests, extract metadata, discover community resources."""
from parse_apis.iiif_ecosystem_api import IIIF, IIIFVersion, ManifestNotFound
client = IIIF()
# Construct a manifest handle (no API call yet — constructible resource).
manifest = client.manifest(id="https://iiif.io/api/cookbook/recipe/0009-book-1/manifest.json")
# Validate the manifest against the IIIF Presentation API 3.0 spec.
validation = manifest.validate(version=IIIFVersion.V3)
print(f"Valid: {validation.okay}, Errors: {validation.error}")
# Normalize metadata from a rights-bearing manifest.
rights_manifest = client.manifest(id="https://iiif.io/api/cookbook/recipe/0008-rights/manifest.json")
metadata = rights_manifest.normalize()
print(f"Title: {metadata.title}, Version: {metadata.version}, Rights: {metadata.rights}")
# List upcoming community events (capped for brevity).
for event in client.events.list(limit=3):
print(event.label, event.type)
# Browse latest news articles.
article = client.articles.list(limit=1).first()
if article:
print(f"Latest: {article.title} ({article.date}) — {article.url}")
# Discover cookbook recipes for implementation patterns.
for recipe in client.recipes.list(limit=3):
print(recipe.name, recipe.url)
# Typed error handling: catch a manifest-not-found condition.
try:
bad = client.manifest(id="https://iiif.io/api/cookbook/recipe/9999-nonexistent/manifest.json")
bad.validate()
except ManifestNotFound as exc:
print(f"Not found: {exc.url}")
print("exercised: manifest.validate / manifest.normalize / events.list / articles.list / recipes.list")
Fetch and parse a IIIF Presentation API manifest from any public URL. Returns the complete manifest JSON including context, type, label, items (canvases with annotation pages and image bodies), behavior, and all other properties defined by the manifest author. The response structure varies by manifest but always includes id, type, and label at minimum.
| Param | Type | Description |
|---|---|---|
| urlrequired | string | The URL of the IIIF manifest to fetch. |
{
"type": "object",
"fields": {
"id": "string, the manifest URI",
"type": "string, the IIIF resource type (e.g. Manifest)",
"items": "array of Canvas objects with annotations and image bodies",
"label": "object with language keys mapping to arrays of label strings"
},
"sample": {
"data": {
"id": "https://iiif.io/api/cookbook/recipe/0009-book-1/manifest.json",
"type": "Manifest",
"items": [
{
"id": "https://iiif.io/api/cookbook/recipe/0009-book-1/canvas/p1",
"type": "Canvas",
"label": {
"en": [
"Blank page"
]
},
"width": 3204,
"height": 4613
}
],
"label": {
"en": [
"Simple Manifest - Book"
]
},
"@context": "http://iiif.io/api/presentation/3/context.json",
"behavior": [
"paged"
]
},
"status": "success"
}
}About the IIIF API
Manifest Fetching and Normalization
The get_manifest endpoint accepts a url parameter pointing to any publicly accessible IIIF manifest and returns the complete parsed document. The response includes id (the manifest URI), type, label (an object mapping language keys to string arrays), and items — an array of Canvas objects that contain annotation pages and image bodies. This gives you the full structure as defined by the manifest author without any field filtering.
The normalize_manifest_metadata endpoint takes the same url input and distills the manifest into a flat, predictable shape. It extracts title from the IIIF label, description from summary or description fields (may contain HTML), a rights URI, and a metadata object mapping label strings to multilingual value objects. It also auto-detects the IIIF Presentation API version — returning "3.0" when an items array is present, "2.0" otherwise.
Validation and Community Data
The validate_manifest endpoint submits a manifest URL to the official presentation-validator.iiif.io service and returns an okay flag (1 for valid, 0 for invalid), an error string, an errorList array of detailed error objects, and a warnings array. An optional version parameter lets you target a specific Presentation API version such as 2.1 or 3.0.
The three community endpoints require no inputs. list_events returns an events array with label, type, time, location, description, organiser, and links for each event, plus a calendar object grouping this week's meetings and all recurring groups. list_news returns articles from the iiif.io news page — each with title, url, ISO date, and excerpt — sorted newest first. list_cookbook_recipes returns the full recipe index as objects containing name and url, covering patterns like simple manifests, rights statements, and multi-page books.
The IIIF API is a managed, monitored endpoint for iiif.io — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when iiif.io changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official iiif.io API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Validate institutional IIIF manifests before publishing to a digital library portal using the
validate_manifestendpoint and checkingerrorList. - Build a manifest metadata ingestion pipeline that uses
normalize_manifest_metadatato extracttitle,rights, andversionacross heterogeneous collections. - Display image canvases and annotation data from remote IIIF manifests by consuming the
itemsarray returned byget_manifest. - Aggregate IIIF community event schedules into an internal calendar using the
eventsandcalendarfields fromlist_events. - Monitor iiif.io news for specification updates by polling
list_newsand filtering by ISOdate. - Surface IIIF Cookbook recipes in a developer documentation site using the
nameandurlfields fromlist_cookbook_recipes. - Auto-detect whether a manifest is IIIF v2 or v3 using the
versionfield in thenormalize_manifest_metadataresponse.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does IIIF.io have an official developer API?+
What does `validate_manifest` actually return when a manifest is invalid?+
okay is set to 0. The error field contains a human-readable error string, errorList is an array of detailed error objects describing each issue, and warnings lists non-fatal concerns. When valid, okay is 1, error is an empty string, and both arrays are empty. The optional version input lets you pin validation to a specific Presentation API version like 2.1 or 3.0.Does the API support fetching individual canvases or image resources within a manifest?+
items array from get_manifest. You would need to traverse that array client-side to access individual canvases. You can fork this API on Parse and revise it to add a dedicated canvas-lookup endpoint if your use case requires it.Can I search or filter IIIF news articles or events by keyword or date range?+
list_news returns all articles sorted newest-first, and list_events returns all upcoming events — neither endpoint accepts filter parameters. Filtering by date or keyword must be done client-side against the returned arrays. You can fork this API on Parse and revise it to add server-side filtering on date, label, or type fields.Does the metadata normalization handle IIIF v2 manifests that use `sequences` instead of `items`?+
normalize_manifest_metadata detects the version based on whether an items array is present, returning "2.0" for manifests that use the older sequences structure. However, the get_manifest endpoint returns the raw manifest as-is, so v2 sequences data will appear in its original form rather than being remapped to items. You can fork the API on Parse and revise it to normalize v2 sequence structures into a unified canvas format.