REST API
Query the Releases index over plain HTTP. This page covers the conventions that apply to every endpoint. The per-endpoint reference is generated from the OpenAPI spec.
- Interactive reference:
api.releases.sh/v1/docs— full Scalar reference with request/response shapes, examples, and client snippets. - OpenAPI 3.1 spec:
api.releases.sh/v1/openapi.json— source of truth for request and response shapes. - Base URL:
https://api.releases.sh/v1 - Errors: Errors — the standardized error envelope, types, and common codes.
- Webhooks: Webhooks — self-serve outbound
release.createddelivery (org-scoped or follows-filtered).
Authentication
Most read endpoints are public. No credentials required.
Operator and write endpoints require a Bearer token with sufficient scope:
curl -H "Authorization: Bearer YOUR_KEY" https://api.releases.sh/v1/...Account endpoints (/v1/me/* — follows, feed, webhooks, API keys) require a signed-in user. Any of these work:
- Browser session — sign in on releases.sh and call the API with credentials included (cookie on same-site requests, or a session token from device login in the CLI).
- User API key — minted via
releases loginor Account → API Keys. Pass asAuthorization: Bearer <key>. - Sign in with Releases — an OAuth access token from an app you've authorized. Pass as
Authorization: Bearer <token>.
User credentials authenticate your account, not operator/admin access. Machine and operator tokens use a separate scope ladder.
Pagination
Different kinds of endpoints paginate differently. There are three shapes:
| Shape | Surfaces | Input | Output |
|---|---|---|---|
| Page-based | Catalog-shaped: /v1/sources, /v1/orgs, /v1/products, /v1/collections | page + limit (default and max 500 unless noted) | { items, pagination }, where pagination: { page, pageSize, returned, totalItems, totalPages, hasMore } |
| Cursor-based | Feed-shaped: /v1/orgs/:slug/releases, /v1/orgs/:orgSlug/sources/:sourceSlug (and its embedded releases array), /v1/orgs/:orgSlug/sources/:sourceSlug/releases, /v1/collections/:slug/releases, /v1/categories/:slug/releases | opaque cursor | pagination: { nextCursor, limit }; nextCursor is null when the slice is exhausted |
| Search | /v1/search, /v1/search/releases | query + limit | _meta.search, with hitCap: true when results saturated limit |
Release date filtering
/v1/search and /v1/releases/latest accept optional since and until query params that limit results by publish date. Each takes an ISO date/datetime (2026-01-01) or a relative shorthand (90d, 4w, 6m, 2y). A value that can't be parsed returns a 400. On /v1/search these params filter the release hits only; the orgs, catalog, and collections sections are unaffected. Releases with no published_at are dropped from the window.
curl "https://api.releases.sh/v1/search?q=slack%20integration&since=90d"
curl "https://api.releases.sh/v1/releases/latest?org=vercel&since=2026-01-01&until=2026-03-31"Resource shape
| Resource | Notes |
|---|---|
| Orgs | Publish releases. Resolved by typed ID (org_…), slug, or a bare domain (primary or alias). |
| Products | Optional grouping layer between orgs and sources. |
| Sources | Changelog endpoints owned by an org. type is one of github, scrape, feed, agent. Resolved by typed ID (src_…) on the bare path, or by slug under the org-scoped path (/v1/orgs/:orgSlug/sources/:sourceSlug). |
| Releases | Carry id, orgId, sourceId, title, version, publishedAt, url, description, media, plus optional summary, title_generated, title_short. |
IDs are immutable; prefer them over slugs.
Lookups
When you only have a coordinate or a domain:
| Endpoint | Resolves |
|---|---|
GET /v1/lookups/by-domain?domain=… | A normalized domain to its owning org and any products whose alias targets the same domain. |
GET /v1/lookups/source-by-slug?slug=… | The canonical org-scoped home for a bare source slug. |
GET /v1/lookups/product-by-slug?slug=… | The canonical org-scoped home for a bare product slug. |
POST /v1/lookups { provider: "github", coordinate: "org/repo" } | Materializes a hidden source row from a GitHub coordinate on first call. |
Upgrade intelligence (Beta)
Beta — subject to change. The shape and parameters of this endpoint may evolve.
GET /v1/whats-changed?package=…&from=…&to=…&ecosystem=npm|pypi|github returns the changelog entries between two versions of a package: the releases in the range (from, to] (from exclusive, to inclusive), each with its summary, breaking-change verdict (none / minor / major / unknown), and any migration notes. Planning an upgrade becomes one call instead of reading many changelog pages.
package— a tracked source slug or a GitHubowner/repocoordinate (passecosystem=githubfor a bare coordinate).- Reads already-indexed releases only — no live fetch.
- An untracked package returns
{ "status": "unknown" }with HTTP 200 (a valid answer, not a 404). npm/PyPI names that aren't yet mapped to a tracked source resolve tounknown. - Wide ranges are truncated to a token budget (newest entries kept), flagged by
truncated.
Also available as the whats_changed MCP tool.
Discoverability
- The API is advertised by RFC 9727 at
/.well-known/api-catalog. - The OpenAPI 3.1 spec is the source of truth:
https://api.releases.sh/v1/openapi.json. - Every org and source page on
releases.shhas machine-readable URL suffixes:.json(programmatic),.md(LLM-friendly),.atom(feed readers).
https://releases.sh/anthropic # HTML
https://releases.sh/anthropic.json # JSON
https://releases.sh/anthropic.md # Markdown
https://releases.sh/anthropic.atom # Atom 1.0 feedLegacy bare paths (/source/{slug}.atom) 308-redirect to the canonical org-scoped form.