Open Data — entry 004 of 44
Archive.org
The Internet Archive's Advanced Search and Metadata APIs let you query and pull structured records for its 99+ million digitized books, web captures, audio, video, and software items. Reads are keyless for both the search endpoint (archive.org/advancedsearch.php) and per-item metadata (archive.org/metadata/{identifier}), returning JSON, XML, or CSV depending on the requested output format.
The Internet Archive exposes its collection — over 124 million items, per a live `q=*:*` count in this run — through two separate, keyless HTTP endpoints rather than one unified API: a Solr-backed advancedsearch.php for querying, and a per-item metadata endpoint for pulling a single item's full record. The two return genuinely different JSON shapes, so code written against one won't parse the other.
GreatAPIs Score
Auth quickstart
- No API key or account is required — both endpoints below are public and keyless reads.
- Request `output=json` explicitly, and note that `output` is the only spelling that works. Both cases probed live in this run: calling `/advancedsearch.php` with no format parameter at all returns `200` with `content-type: text/html; charset=UTF-8` — a full HTML search-results page — while `format=json` is rejected outright, returning `200 text/html` with the body `[UNSUPPORTED_VALUE] A requested parameter has an inappropriate value json for request parameter format`.
- CORS is open on both endpoints: a probe in this run confirmed `access-control-allow-origin: *` on `/advancedsearch.php` and on `/metadata/{identifier}`, both bare and with an `Origin: https://example.com` header.
Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.
Search items by title
GEThttps://archive.org/advancedsearch.php?q=title%3A(python)&fl[]=identifier&fl[]=title&fl[]=mediatype&rows=2&output=json
{"responseHeader":{"status":0,"QTime":27,"params":{"query":"title:python","qin":"title:(python)","fields":"identifier,title,mediatype","wt":"json","rows":2,"start":0}},"response":{"numFound":8564,"start":0,"docs":[{"identifier":"soundcloud-245108190","mediatype":"audio","title":"FULL: Monty Python vs. PC police - 2/2/16"},{"identifier":"pbscelyc7gi5n9yygcywnio7wttmdgzstfjbqris","mediatype":"audio","title":"Scalable Python for Everyone, Everywhere // Matthew Rocklin // MLOps Meetup #38"}]}}rows=2 was requested directly in this run's probe (not truncated after capture) — both returned docs are complete, unmodified objects. `response.numFound` (8564 at probe time) reflects the full match count across the whole corpus, not just the returned page.
Developer reference
https://archive.orgGotchas & limits
- Omitting `output=json` silently returns an HTML search-results page instead of an error — confirmed live in this run (see authSteps). Always set it explicitly rather than assuming JSON is the default.
- `/metadata/{identifier}` returns a completely different shape from `/advancedsearch.php`'s Solr-style `{responseHeader, response:{numFound,start,docs}}`. A live probe of `/metadata/pbscelyc7gi5n9yygcywnio7wttmdgzstfjbqris` (one of this example's own search hits) returned exactly these 13 top-level keys: `alternate_locations, created, d1, d2, dir, files, files_count, item_last_updated, item_size, metadata, server, uniq, workable_servers`. Note what is *not* there: `identifier` is not a top-level key — it lives at `metadata.identifier`, alongside the item's title/creator/description. The file listing is a separate top-level `files` array.
- The `/metadata/{identifier}` top-level key set varies by item, so don't hard-code it. Probed live in this run: the 13 keys above for one item, but `/metadata/nasa` returns those same 13 plus `is_collection` and `reviews`. `metadata`, `files`, and `files_count` were present on both — treat those as the stable ones and probe before depending on anything else.
- Requesting `/metadata/{identifier}` for an identifier that does not exist returns `200` with an empty JSON object `{}` — confirmed live in this run — not a 404 or an error body. Check for an empty object rather than relying on HTTP status to detect a missing item.