ARTICLE 01 · API · agentlist.io · 2026-09-25 · 6 min read

Every AI agent on one endpoint

The catalog is data, not just pages — one JSON response carries every system, its spec fields, and its last change.

Every page on this site renders from the same normalized catalog — and the catalog itself is public. One GET against /api/v1/systems returns all 112 systems, 89 vendors' names resolved, each record carrying the spec fields the site normalizes: category, interfaces, hosting, pricing, status. No auth, CORS open, cached at the edge for a day.

curl -s https://www.agentlist.io/api/v1/systems | jq '.meta.counts'
# → { "systems": 96, "vendors": 77, "categories": 14 }

What a record looks like

Each entry in systems[] is one catalog record — the same shape whether it's a VS Code fork or a phone-answering agent:

slug / name / title
Stable identifier, seed name, display name — the slug is the spec-page URL.
category
One of the fifteen catalog categories (ai-ide, digital-employee, agent-communication, agent-services, …).
vendor
The organization behind the system, resolved from its vendor id.
interfaces
How you drive it: editor, cli, api, chat, browser, voice.
hosting
local, cloud, or both.
pricing
List price as verified on the last catalog pass — hedge words ("verify") mark stale figures.
status
active, active-caution, or deprecated — caution flags stale repos, removed tiers, pivots.
aliases
Other names the system is known by (renames, codenames, upstream project names).
summary / sources
The one-paragraph editorial summary plus the URLs it was checked against.
lastChanged
The system's most recent changelog entry, or null if it's never moved.
url
Canonical spec-sheet URL on agentlist.io — link here, don't copy data.

Useful slices

The endpoint is deliberately flat — filter client-side. A few slices that matter:

# every digital employee
curl -s https://www.agentlist.io/api/v1/systems \
  | jq '[.systems[] | select(.category=="digital-employee") | .title]'

# open-source agents with GitHub repos
curl -s https://www.agentlist.io/api/v1/systems \
  | jq '[.systems[] | select(.sources[]? | test("github.com")) | {title, sources}]'

# systems flagged for caution (stale repos, removed tiers)
curl -s https://www.agentlist.io/api/v1/systems \
  | jq '[.systems[] | select(.status=="active-caution") | .title]'

In an app, it's one fetch — the payload is a few hundred KB and changes at catalog-cadence, not request cadence:

const { systems } = await fetch("https://www.agentlist.io/api/v1/systems").then(r => r.json())
const comms = systems.filter(s => s.category === "agent-communication")

Tracking what changed

Two feeds sit next to the endpoint for diff-tracking. /api/v1/changelog returns the structured changelog (adds, repricings, cautions, retirements), and /feed.xml is the same stream as RSS for reader subscriptions. Each system record also carries lastChanged — its latest changelog entry — so a sync pass can skip records that haven't moved.

Verified-as-of is the first field in meta: generatedAt is the seed's verification date (currently 2026-09-25), not the deploy timestamp.

Etiquette

Cache it — the response is built to be stored, and s-maxage=86400 means the edge serves a day-old copy anyway. Don't scrape the HTML pages for the same data; the JSON is canonical and cheaper for everyone. When you publish against it, link the url field — spec pages carry the caveat text and changelog context a raw record can't.