Skip to content

Version 1 · read-only

Public API.

The same public record as the site, as JSON. No key, no sign-up, no writes. Open CORS, so you can call it from a browser.

How it works

  • Data comes from the site snapshot and changes only when a new weekly snapshot ships. Responses are cached for up to an hour at the edge and carry an ETag.
  • Every response states its source (GitHub Sponsors, Open Collective, Open Source Pledge or a company's own program), the snapshot date and the denylist version.
  • Private GitHub Sponsors amounts are never published: amount_usd is null and private is true.
  • Spam, excluded companies (see the method) and companies on a weekly hold are left out of every route.
  • Basic rate limit: 60 requests per minute per client IP. The counter is kept per server instance, not globally, so it is a backstop rather than a hard quota, and responses served from the edge cache are not counted. Over the limit you get a 429 with a Retry-After header.
  • An entry that is not public (spam, excluded, or on a weekly review hold until its review date) returns the same 404 as an unknown slug: "Not available in the public API." Unknown /api routes also return a JSON 404.
  • Amounts are in USD. Open Collective figures are cumulative, Pledge figures are annual.

Response shape

{
  "meta": {
    "api_version": "v1",
    "snapshot_date": "2026-10-06",
    "snapshot_hash": "b3cff2ed...",
    "denylist_version": "2026-10-12.4",
    "sources": [{ "key": "oc", "name": "Open Collective" }]
  },
  "pagination": { "page": 1, "per_page": 50, "total": 120, "total_pages": 3 },
  "data": [ ... ]
}

A private amount looks like this:

{
  "source": "gh",
  "source_name": "GitHub Sponsors",
  "amount_usd": null,
  "private": true
}

Errors (400, 404, 405, 429) use { "meta": { ... }, "error": { "status", "message" } } with the matching HTTP status. On /api/movements, snapshot_date is the week you asked for.

Endpoints

GET /api/projects

Open source projects named by at least 3 companies, most sponsors first.

pagePage number, from 1. Default 1.
per_pageItems per page, 1 to 100. Default 50.
sourceOnly projects with a sponsorship from this source: gh, oc, osp or own.
qText match on the project slug or name.
sponsorOnly projects funded by this company slug.
min_sponsorsMinimum number of sponsoring companies. Default and floor 3.

Try it: /api/projects?source=oc&per_page=20

GET /api/projects/{slug}

One project with every company that names it, the source and the public amount.

Try it: /api/projects/webpack

GET /api/sponsors/{slug}

One company: rank, public total, totals by source and each sponsorship.

Try it: /api/sponsors/getsentry

GET /api/movements?week=YYYY-MM-DD

Weekly changes from the scraper: new and disappeared sponsors, amount changes, new GitHub sponsorships, beneficiary count changes and renames. A 404 lists the available weeks.

weekRequired. Date of the weekly snapshot, for example 2026-10-12.

Try it: /api/movements?week=2026-10-06

GET /api/denylist

The public spam denylist, the same file as /denylist.json.

Try it: /api/denylist