← All guides

πŸ“‘ We check api.publicapis.org (and 85+ other public dev APIs) with a plain GET every 30 minutes β€” see the live status page. The domain doesn't resolve at all.

Public APIs directory alternative β€” the API that listed every API is gone

GitHub's public-apis list is one of the most-starred repositories on the planet β€” 481,000+ stars β€” and for years it had an HTTP face: api.publicapis.org. It's the API behind a whole tutorial genre. "Build an API explorer", "fetch and filter with React", "async/await practice" β€” they all start with the same line:

fetch('https://api.publicapis.org/entries')
// TypeError: Failed to fetch

curl 'https://api.publicapis.org/entries'
# curl: (6) Could not resolve host: api.publicapis.org

That's the response today β€” checked live on September 19, 2026. Not a 404, not a timeout: the whole publicapis.org domain is NXDOMAIN, homepage included. The request dies at DNS, so there's no status code to branch on β€” fetch() rejects outright and every .then(r => r.json()) chain in those tutorials throws. The companion server repo (davemachado/public-api), which the list's README still links, had its last commit in December 2022. And the community mirror many tutorials switched to, api.publicapis.dev, is gone too β€” it answers with a Vercel DEPLOYMENT_NOT_FOUND page (also checked today).

Honestly: this API earned its retirement story. It was free, keyless, CORS-open, and it taught an enormous number of people what query parameters are. The markdown list it fronted is still actively maintained β€” the data lives on; only the API died. Which means the fix is simple: host the data yourself.

1. Host 839 real entries in one curl

curl -s https://mockbird.mockbird.workers.dev/data/publicapis.db.json \
  | curl -s -X POST 'https://mockbird.mockbird.workers.dev/api/projects/import?name=public-apis' \
    -H 'content-type: application/json' --data-binary @-
# β†’ {"id":"YOUR_ID","adminKey":"…"}  β€” save both

The dataset is parsed from the current README of the GitHub list (September 2026): 839 entries across all 51 categories (capped at 19 per category to fit the free import limits β€” the full list has ~1,850), in the dead API's exact field shape: API, Description, Auth, HTTPS (boolean), Cors (yes/no/unknown), Link, Category. A second categories collection holds all 51 category names with per-category counts.

2. The translation table

The original's query params were substring-or-exact filters. Same moves here:

api.publicapis.orgYour Mockbird project
/entries/entries β€” full list, X-Total-Count: 839
/entries?title=cat/entries?API_like=cat β€” case-insensitive substring
/entries?description=dog/entries?Description_like=dog
/entries?category=Animals/entries?Category=Animals (or Category_like=anim)
/entries?https=true/entries?HTTPS=true
/entries?auth=apiKey/entries?Auth=apiKey
/random/entries?sortBy=random&limit=1
/categories/categories β€” 51 records with counts
pagination: none?page=2&limit=25 β€” it has some now
writes: nonePOST /entries β€” persists, visible in every later GET
curl "https://mockbird.mockbird.workers.dev/m/YOUR_ID/entries?API_like=cat&select=API,Category"
# β†’ 11 entries: Cat Facts, HTTP Cat, Catboy, Catalogopolis…

curl "https://mockbird.mockbird.workers.dev/m/YOUR_ID/entries?Auth=apiKey&limit=3"
# β†’ 3 of the 370 entries that need an API key

3. The exact {"count":…,"entries":[…]} envelope

The dead API didn't return a bare array β€” it wrapped everything as {"count": N, "entries": [...]}, and tutorial code reads data.entries.map(...). Reproduce that shape with a response envelope template (URL-encoded {"count":"$count","entries":"$data"}):

curl "https://mockbird.mockbird.workers.dev/m/YOUR_ID/entries?Category=Animals&mock_envelope=%7B%22count%22%3A%22%24count%22%2C%22entries%22%3A%22%24data%22%7D"
# β†’ {"count": 19, "entries": [ { "API": "Axolotl", … } ]}

Or set it once as the project default, and every GET answers in the old shape with no query param at all β€” old tutorial code runs unchanged except for the base URL:

curl -X PUT https://mockbird.mockbird.workers.dev/api/projects/YOUR_ID/settings \
  -H 'x-admin-key: YOUR_ADMIN_KEY' -H 'content-type: application/json' \
  -d '{"envelope":"{\"count\":\"$count\",\"entries\":\"$data\"}"}'

4. /random, and a directory that accepts submissions

curl "https://mockbird.mockbird.workers.dev/m/YOUR_ID/entries?sortBy=random&limit=1&select=API,Link"

# the original list takes pull requests; your directory takes POSTs:
curl -X POST https://mockbird.mockbird.workers.dev/m/YOUR_ID/entries \
  -H 'content-type: application/json' \
  -d '{"API":"My Side Project","Description":"The API I am actually building","Auth":"","HTTPS":true,"Cors":"yes","Link":"https://example.dev","Category":"Development"}'
# β†’ id 840 β€” and it's really there in the next GET

That last curl is the point where this stops being a nostalgia exercise: an "API explorer" tutorial built against your own project can add a submit form β€” the thing no tutorial could ever build against the read-only original.

5. Rehearse the way it died

NXDOMAIN means fetch() rejects before any HTTP happens β€” the catch-block path most explorer tutorials never wrote. You can't fake DNS with a status code, but you can make sure both failure paths are real: point one test at a domain that doesn't resolve (rejection path), and drill the HTTP-error path deterministically here:

# three calls: 503, 503, then success β€” retry/backoff drill
curl "https://mockbird.mockbird.workers.dev/m/YOUR_ID/entries?mock_seq=503,503,200&limit=1"

# slow directory, for spinner/timeout states
curl --max-time 2 "https://mockbird.mockbird.workers.dev/m/YOUR_ID/entries?mock_delay=5000"

More recipes in testing loading & error states.

If you want the real, full directory

Our dataset is a point-in-time subset for development β€” not a maintained catalogue. The honest state of the genre (all checked September 19, 2026): the GitHub list itself is alive and actively maintained β€” it's markdown, not an API, but it's the source of truth. freepublicapis.com is a living alternative with its own JSON API (different response shape, ~400 tested entries). And if you need today's full 1,850-entry list as an API, the honest answer is the same pattern as this whole guide: parse the README and host it yourself β€” the shape above is exactly what that looks like. Point development, tests, CI, and demos at data you control.

Start now

The one-curl import in section 1, or zero setup at all:

curl https://mockbird.mockbird.workers.dev/m/demo/products?limit=3

Facts checked live on September 19, 2026: api.publicapis.org/entries, /random, and the publicapis.org homepage all fail DNS resolution (curl: (6) Could not resolve host, NXDOMAIN from the resolver); api.publicapis.dev/entries answers HTTP 404 with Vercel's DEPLOYMENT_NOT_FOUND body; the GitHub list showed 481,616 stars with a push on September 18, 2026; davemachado/public-api's last commit is dated December 8, 2022; freepublicapis.com's API answered 200. Every Mockbird command on this page was run against a live project before publishing.

Full API reference in the docs. More guides: covid19api alternative Β· GitHub Jobs alternative Β· Free fake REST API Β· Host a JSON file as an API Β· CSV to REST API. Create your API β†’

⚑ Skip the terminal: this link opens the dashboard's import panel β€” paste the dataset from section 1 and you're done. No signup.