What this is
A documented, keyless HTTP interface over the PulseGate index. There is no registration, no API key, and no account: the endpoints below answer public GET requests within published limits.
We document a deliberately small part of what the service answers. An endpoint on this page has a shape we will not change without notice. An endpoint that is not on this page may answer today and stop tomorrow, and that is the documented behaviour.
What this is not: a review source, an endorsement, a ranking, a scoring service, or investment or legal advice. The index records what public sources say and where we read it. It does not rate anything.
Endpoints
Two tiers, and the difference matters. The agent-facing tier is open in robots.txt to the crawlers of OpenAI, Anthropic and Perplexity; the client-facing one is excluded from crawling.
- Agent-facing, open to the OpenAI, Anthropic and Perplexity crawlers — GET /api/search · GET /api/apps · GET /api/apps/facets · GET /api/categories · GET /api/stats/public
- Client-facing, excluded from crawling in robots.txt — GET /api/apps/{slug}
/api/apps/{slug} is documented for programs that call it directly. It is uncached, costs a database read per request, and returns fields that are already on the crawlable HTML record page, so an agent that honours robots.txt should read the record page instead. This is deliberate, not an oversight.
GET /api/search — ask a question
Parameters: q (the query, truncated at 120 characters); page (1-50); platform, license, pricing and category to narrow the answer.
One envelope is returned for every outcome, including no results and internal failure, so a consumer never has to tell an error payload from an empty one: shape, query, lead, results, nearest, relaxedBy, axes, scope, tookMs.
- The result list is capped at 10 rows. A limit above that is accepted and ignored, and the response does not echo it back — so do not infer page size from your request.
- scope.matched tells you how many rows matched; scope.available how many you can reach.
- This endpoint is not cached. A first call after a quiet period has been measured at about 10 seconds; warm calls at about 13 milliseconds. Budget for the cold one.
GET /api/apps — page the catalogue
Filters are documented in the response itself: /api/apps/facets returns every facet and its counts, /api/categories the category tree.
Three behaviours you must know before you build on it:
- An unknown parameter is ignored silently. A typo does not produce an error, it produces different data. Check your parameter names against /api/apps/facets.
- Applying any filter changes the default ordering from balanced to firstSeen. Read meta.order; do not assume it.
- items and apps are the same array. Read items; apps is legacy and may go.
Depth: page is at most 50 and the offset at most 5,000, whichever binds first. Beyond that the response is 403 with {"error":"pagination_limit"}. limit is clamped to 100.
GET /api/apps/{slug} — one record
Client-facing tier, see above. Returns the public fields of a single record.
A record outside the catalogue is absent, not hidden inside the payload: deleted, taken down by an administrator, unlisted, not eligible, excluded by curation, or folded into another record as a duplicate, it answers 404 — the same as a slug this index does not hold. A record confirmed gone is still in the catalogue, still answers, and says so in its own fields.
GET /api/stats/public — the published figures
Index size, recent indexing volume, and a seven-day daily series. Every figure carries the window it covers: a bare count with no window and no date is not a claim we stand behind, because the index changes daily.
Limits
Per minute, per IP — this is the one you will meet:
- 80 per minute — /api/apps, /api/apps/facets, /api/search
- 60 per minute — /api/categories, /api/stats/public
Per day, per IP, there is also a ceiling on bursts: 20,000 for /api/apps and the paths beneath it, and 5,000 for /api/search. It is counted only once a client has gone over roughly 30 requests in a minute, so a client that stays under the per-minute limits is never charged against it. We state it because it binds a burst, not because it is a budget to plan around.
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, on 200 as well as on 429; a 429 adds Retry-After. On a response served from the edge cache those three describe the request that filled the cache, not yours.
Do not work around a limit. Access within the published limits is permitted; access that exceeds or circumvents them is not, and section 7 of the Terms applies to it.
What the fields mean — and what they do not
We would rather be dull and correct than confident and wrong. Three fields need saying plainly.
aliveStatus is one of alive, gone, or unverified:
- gone means a liveness check ran and found the thing gone.
- alive means a liveness check ran and found it there.
- unverified means we have not established it — not "probably alive". It is a different kind of statement, not a weaker one. A record we fetched successfully but never assessed is unverified, because a 200 is the absence of bad news and not a positive finding.
lastCheckedAt is the time of the liveness check. If no check has run, it is null. It is never filled in from some other date we happen to hold.
firstSeenAt is when this index first saw the record — not when the software was released. One exception, stated with its number so nobody reads past it: for records indexed before October 1, 2026 it is often an estimate placed shortly after the record's documented release, by a historical backfill we have since stopped. Measured on October 2, 2026, firstSeenAt precedes the record's own creation in this index by more than a day for 178,995 of 354,118 records, which is 50.6 per cent, and the earliest such value is January 1, 2022. Treat it as a lower bound on age for anything older than October 2026, not as an observation. Where we have a documented release date it is a separate field with its own provenance.
Stability
Fields on this page will not be removed without notice. Endpoints not on this page carry no such promise: if you build on something undocumented and it changes, that is the documented behaviour.
Terms
Use of the endpoints on this page, within the published limits, is expressly permitted under section 7.1 of our Terms. That permission covers access; it does not by itself grant redistribution of substantial portions of the index.
This page applies as published from time to time. Effective date: October 1, 2026. A change to the endpoints, their limits, or this permission is not retroactive: access that complied with the permission in effect at the time of access does not become a violation because this page later changed. Previous versions are kept and available on request.